generic-match: First class pattern matching

[ data, library, mit ] [ Propose Tags ]

First class pattern matching.


[Skip to Readme]
Versions [faq] 0.1.0.0, 0.2.0.0, 0.2.0.1, 0.2.0.2, 0.3.0.0
Change log CHANGELOG.md
Dependencies base (>=4.12 && <4.15), generics-sop (==0.5.*) [details]
License MIT
Copyright 2020 Samuel Schlesinger
Author Samuel Schlesinger
Maintainer sgschlesinger@gmail.com
Category Data
Source repo head: git clone https://github.com/samuelschlesinger/generic-match
Uploaded by sgschlesinger at 2020-08-29T21:02:13Z
Distributions NixOS:0.3.0.0
Downloads 264 total (9 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Hackage Matrix CI
Docs available [build log]
Last success reported on 2020-08-29 [all 1 reports]

Modules

[Index] [Quick Jump]

Downloads

Maintainer's Corner

For package maintainers and hackage trustees


Readme for generic-match-0.3.0.0

[back to package description]

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.