MyNixOS website logo
Description

First class pattern matching.

generic-match

Hackage Build Status

What?

An implementation of first-class pattern matches in Haskell, based on generics-sop.

Why?

Oftentimes, when writing Haskell code, we want to branch on multiple cases of a sum type, such as

data TravelMethod
  = Airplane Airport UTCTime
  | Train TrainStation UTCTime
  | Driving

For instance, lets say that we want to grab out the time. In Haskell, we can do this by writing:

timeOfTravel :: TravelMethod -> Maybe UTCTime
timeOfTravel = \case
  Airplane _airport time -> Just time
  Train _trainStation time -> Just time
  Driving -> Nothing

This is concise, and preferable to many other languages, but in this case we can do even better using this library.

timeOfTravel travelMethod = match travelMethod (Just . flip const) (Just . flip const) Nothing

In this example, perhaps we don't save much, but I hope the principle is clear. The case for using this library is when you want to branch on the contents of each different sum, and you already have functions or concise combinators to build functions that handle your inputs. For a Haskeller, this is already rather familiar, I claim!

either l r x == match x l r
maybe n j x == match x n j

Examples

data DatabaseAccess a =
    ConnectionFailure String
  | InvalidRowCount Int
  | Successful a
  deriving (GHC.Generic, Generic)

doThing :: m (DatabaseAccess Bool)

...

x <- doThing >>= \g -> match g error (error . show) pure

Contribution

Contributions are very welcome! Feel free to create an issue or a PR or ping me on any platform to chat about whatever, especially improvements to my libraries.

Compatibility

I support all of the GHC versions that I typically do in my code, from 8.6.1 to 8.10.2. I build locally on Mac, and my travis builds are on Linux, so if you run into problems on Windows, let me know. If you want to be sure that a build will pass, run the test script in this repository.

Metadata

Version

0.3.0.1

License

Platforms (75)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    WASI
    Windows
Show all
  • aarch64-darwin
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64_be-none
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-darwin
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-darwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • vc4-none
  • wasm32-wasi
  • wasm64-wasi
  • x86_64-cygwin
  • x86_64-darwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-windows