Created
March 9, 2019 00:20
-
-
Save fghibellini/aeaf8b7b1f12baac268d309775362335 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- | Can pattern match on nonempty lists | |
-- | |
-- @ | |
-- import Custom.NonEmpty (head, pattern NEL) | |
-- let arr = [1,2,3] | |
-- case arr of | |
-- NEL ne -> head ne | |
-- [] -> 42 | |
-- @ | |
-- | |
-- This is an instance of [Explicitly-bidirectional pattern synonyms](https://ghc.haskell.org/trac/ghc/wiki/PatternSynonyms#Explicitly-bidirectionalpatternsynonyms). | |
-- It allows us to specify a pattern @NEL rs@ that can be used anywhere the @x:xs@ pattern is used, but instead of binding the two variables @x@ and @xs@ to the head and tail of the list, | |
-- it takes the head and tail and combines them into a `NonEmpty` instance that is then bound to the variable @rs@. | |
-- This is possible because x:xs and (x:|xs) are isomorphic. | |
-- The bidirectional pattern synonym works by defining the two directions of the isomorphism one on the right side of `<-` and one in the where clause. | |
-- The first (@(nonEmpty -> Just xs)@) relies on the [ViewPatterns extension](https://ghc.haskell.org/trac/ghc/wiki/ViewPatterns) that allows us to run an arbitrary | |
-- function to transform a @[a]@ into a @NonEmpty a@. | |
-- | |
-- `ViewPatterns` breaks the pattern exhaustiveness checker of the compiler so we use the @COMPLETE@ pragma to tell GHC that if the user | |
-- pattern matches on @[]@ and @NEL xs@ then he has handled all the cases. | |
pattern NEL :: NonEmpty a -> [a] | |
pattern NEL xs <- (nonEmpty -> Just xs) | |
where NEL xs = toList xs | |
{-# COMPLETE [], NEL #-} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment