Portability | non-portable (see .cabal) |
---|---|
Stability | experimental |
Maintainer | Brent Yorgey <byorgey@cis.upenn.edu> |
Safe Haskell | None |
A collection of useful pattern combinators.
- var :: Pattern `[a]` a
- give :: b -> Pattern `[b]` a
- __ :: Pattern `[]` a
- pfail :: Pattern `[]` a
- cst :: Eq a => a -> Pattern `[]` a
- (/\) :: Pattern vs1 a -> Pattern vs2 a -> Pattern (vs1 :++: vs2) a
- (\/) :: Pattern as a -> Pattern as a -> Pattern as a
- view :: (a -> b) -> Pattern vs b -> Pattern vs a
- (-->) :: (a -> b) -> Pattern vs b -> Pattern vs a
- tryView :: (a -> Maybe b) -> Pattern vs b -> Pattern vs a
- (-?>) :: (a -> Maybe b) -> Pattern vs b -> Pattern vs a
- is :: (a -> Bool) -> Pattern `[]` a
- pfilter :: (Distribute vs, Foldable t) => Pattern vs a -> Pattern (Map [] vs) (t a)
- pmap :: (Distribute vs, Traversable t) => Pattern vs a -> Pattern (Map t vs) (t a)
- pfoldr :: (Foldable t, Functor t) => Pattern vs a -> Fun vs (b -> b) -> b -> Pattern `[b]` (t a)
- match :: a -> Clause a r -> r
- tryMatch :: a -> Clause a r -> Maybe r
- mmatch :: Monad m => m a -> Clause a (m b) -> m b
- elim :: Clause a r -> a -> r
- true :: Pattern `[]` Bool
- false :: Pattern `[]` Bool
- unit :: Pattern `[]` ()
- tup0 :: Pattern `[]` ()
- pair :: Pattern vs1 a -> Pattern vs2 b -> Pattern (vs1 :++: vs2) (a, b)
- tup2 :: Pattern vs1 a -> Pattern vs2 b -> Pattern (vs1 :++: vs2) (a, b)
- tup3 :: Pattern vs1 a -> Pattern vs2 b -> Pattern vs3 c -> Pattern (vs1 :++: (vs2 :++: vs3)) (a, b, c)
- tup4 :: Pattern vs1 a -> Pattern vs2 b -> Pattern vs3 c -> Pattern vs4 d -> Pattern (vs1 :++: (vs2 :++: (vs3 :++: vs4))) (a, b, c, d)
- tup5 :: Pattern vs1 a -> Pattern vs2 b -> Pattern vs3 c -> Pattern vs4 d -> Pattern vs5 e -> Pattern (vs1 :++: (vs2 :++: (vs3 :++: (vs4 :++: vs5)))) (a, b, c, d, e)
- nothing :: Pattern `[]` (Maybe a)
- just :: Pattern vs a -> Pattern vs (Maybe a)
- left :: Pattern vs a -> Pattern vs (Either a b)
- right :: Pattern vs b -> Pattern vs (Either a b)
- nil :: Pattern `[]` [a]
- cons :: Pattern vs1 a -> Pattern vs2 [a] -> Pattern (vs1 :++: vs2) [a]
- zero :: (Integral a, Eq a) => Pattern `[]` a
- suc :: (Integral a, Eq a) => Pattern vs a -> Pattern vs a
- mk0 :: (a -> Maybe ()) -> Pattern `[]` a
- mk1 :: (a -> Maybe b) -> Pattern vs b -> Pattern vs a
- mk2 :: (a -> Maybe (b, c)) -> Pattern vs1 b -> Pattern vs2 c -> Pattern (vs1 :++: vs2) a
- mk3 :: (a -> Maybe (b, c, d)) -> Pattern vs1 b -> Pattern vs2 c -> Pattern vs3 d -> Pattern (vs1 :++: (vs2 :++: vs3)) a
- mk4 :: (a -> Maybe (b, c, d, e)) -> Pattern vs1 b -> Pattern vs2 c -> Pattern vs3 d -> Pattern vs4 e -> Pattern (vs1 :++: (vs2 :++: (vs3 :++: vs4))) a
- mk5 :: (a -> Maybe (b, c, d, e, f)) -> Pattern vs1 b -> Pattern vs2 c -> Pattern vs3 d -> Pattern vs4 e -> Pattern vs5 f -> Pattern (vs1 :++: (vs2 :++: (vs3 :++: (vs4 :++: vs5)))) a
Pattern combinators
Basic patterns
give :: b -> Pattern `[b]` aSource
give b
always succeeds, ignoring the matched value and
providing the value b
instead. Useful in conjunction with
(
for providing default values in cases that would otherwise
not bind any values.
/\
)
Wildcard pattern: always succeeds, binding no variables. (This is written as two underscores.)
cst :: Eq a => a -> Pattern `[]` aSource
Constant pattern: test for equality to the given constant.
cst x = is (==x)
.
(/\) :: Pattern vs1 a -> Pattern vs2 a -> Pattern (vs1 :++: vs2) aSource
Conjunctive (and) pattern: matches a value against two patterns, and succeeds only if both succeed, binding variables from both.
(/\) = mk2
(\a -> Just (a,a))
(\/) :: Pattern as a -> Pattern as a -> Pattern as aSource
Disjunctive (or) pattern: matches a value against the first pattern, or against the second pattern if the first one fails.
view :: (a -> b) -> Pattern vs b -> Pattern vs aSource
View pattern: do some computation, then pattern match on the result.
tryView :: (a -> Maybe b) -> Pattern vs b -> Pattern vs aSource
Partial view pattern: do some (possibly failing) computation, then pattern match on the result if the computation is successful.
Computational patterns
pfilter :: (Distribute vs, Foldable t) => Pattern vs a -> Pattern (Map [] vs) (t a)Source
pfilter p
matches every element of a Foldable
data structure
against the pattern p
, discarding elements that do not match.
From the matching elements, binds a list of values corresponding
to each pattern variable.
pmap :: (Distribute vs, Traversable t) => Pattern vs a -> Pattern (Map t vs) (t a)Source
pmap p
matches every element of a Traversable
data
structure against the pattern p
. The entire match fails if any
of the elements fail to match p
. If all the elements match,
binds a t
-structure full of bound values corresponding to each
variable bound in p
.
pfoldr :: (Foldable t, Functor t) => Pattern vs a -> Fun vs (b -> b) -> b -> Pattern `[b]` (t a)Source
pfoldr p f b
matches every element of a Foldable
data
structure against the pattern p
, discarding elements that do
not match. Folds over the bindings produced by the matching
elements to produce a summary value.
The same functionality could be achieved by matching with
pfilter p
and then appropriately combining and folding the
resulting lists of bound values. In particular, if p
binds
only one value we have
match t (pfoldr p f b ->> id) === match t (pfilter p ->> foldr f b)
However, when p
binds more than one value, it can be convenient
to be able to process the bindings from each match together,
rather than having to deal with them once they are separated out
into separate lists.
Running matches
match :: a -> Clause a r -> rSource
match
satisfies the identity match a c = fromJust (tryMatch a c)
.
tryMatch :: a -> Clause a r -> Maybe rSource
"Runs" a Clause
, by matching it against a value and returning
a result if it matches, or Nothing
if the match fails.
mmatch :: Monad m => m a -> Clause a (m b) -> m bSource
mmatch m p = m >>= elim
p
Useful for applicative-looking monadic pattern matching, as in
ex7 :: IO () ex7 = mmatch getLine $ cst "" ->> return () <|> var ->> putStrLn . ("You said " ++)
Patterns for common data types
Booleans
Tuples
If you need to pattern match on tuples bigger than 5-tuples, you are Doing It Wrong.
pair :: Pattern vs1 a -> Pattern vs2 b -> Pattern (vs1 :++: vs2) (a, b)Source
Construct a pattern match against a pair from a pair of patterns.
tup3 :: Pattern vs1 a -> Pattern vs2 b -> Pattern vs3 c -> Pattern (vs1 :++: (vs2 :++: vs3)) (a, b, c)Source
Match a 3-tuple.
tup4 :: Pattern vs1 a -> Pattern vs2 b -> Pattern vs3 c -> Pattern vs4 d -> Pattern (vs1 :++: (vs2 :++: (vs3 :++: vs4))) (a, b, c, d)Source
Match a 4-tuple.
tup5 :: Pattern vs1 a -> Pattern vs2 b -> Pattern vs3 c -> Pattern vs4 d -> Pattern vs5 e -> Pattern (vs1 :++: (vs2 :++: (vs3 :++: (vs4 :++: vs5)))) (a, b, c, d, e)Source
Match a 5-tuple.
Maybe
Either
Lists
Numerics
Building your own patterns
Smart constructors for patterns
Build patterns from a selector function.
mk3 :: (a -> Maybe (b, c, d)) -> Pattern vs1 b -> Pattern vs2 c -> Pattern vs3 d -> Pattern (vs1 :++: (vs2 :++: vs3)) aSource