-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | First class patterns and pattern matching, using type families -- -- This package implements a library of first class patterns. The initial -- basis for this library was Morten Rhiger's "Type-safe pattern -- combinators"; the patterns can be used in an almost identical way to -- those of Morten Rhiger. In a series of blog posts at -- http://reinerp.wordpress.com/category/pattern-combinators/ the -- types of patterns were made more revealing using type families, and a -- simpler implementation was used which avoids some book-keeping. -- -- The library reimplements most of Haskell's built-in pattern matching -- facilities, plus some more. The pattern matches of this library are -- lightweight: when GHC's optimisation is turned on, all overhead should -- be optimised away, leaving a standard Haskell pattern match. @package first-class-patterns @version 0.2.0 -- | Type-level lists. These lists only describe the types, but contain no -- data. That is, they are phantom types. module Data.Pattern.Base.TypeList -- | The type of empty lists data Nil -- | (:*:) corresponds to cons. data (:*:) h t -- | Concatenation of lists. Instances: -- --
-- type instance Nil :++: xs = xs -- type instance (h:*:t) :++: xs = h :*: (t :++: xs) ---- | Various types defined inductively as type families or data families on -- type-lists. module Data.Pattern.Base.Tuple -- | Curried functions. We have -- --
-- Fun (x1 :*: x2 :*: ... :*: xn :*: Nil) r ~ x1 -> x2 -> ... -> xn -> r ---- | Tuples with types given by xs. data Tuple xs -- | The empty tuple zero :: Tuple Nil -- | The singleton tuple one :: a -> Tuple (a :*: Nil) -- | Concatenation of tuples. (<>) :: Tuple xs -> Tuple ys -> Tuple (xs :++: ys) -- | Runs a tuple by applying it to a function. runTuple :: Tuple xs -> Fun xs r -> r -- | The main types used. module Data.Pattern.Base -- | The pattern type. A Pattern vars a is a pattern which matches -- against as and binds variables with types given by the -- type-list vars. -- -- Although this is the basic type used by patterns, many of pattern -- combinators (for instance, Data.Pattern.Base.Common.left) -- have types better expressed by the type synonyms Pat0, -- Pat1, Pat2, etc, Pat5, so that nesting of -- patterns (e.g. left (tup2 var var)) can be written as -- function application. -- -- Most "normal" pattern matchers (in fact, all of the matchers in -- Data.Pattern.Common except var and (/)) can -- be conveniently defined using mk0, mk1, etc, -- mk5. newtype Pattern vars a Pattern :: (a -> Maybe (Tuple vars)) -> Pattern vars a runPattern :: Pattern vars a -> a -> Maybe (Tuple vars) type Pat0 a = Pattern Nil a type Pat1 b a = forall bs. Pattern bs b -> Pattern bs a type Pat2 b c a = forall bs cs. Pattern bs b -> Pattern cs c -> Pattern (bs :++: cs) a type Pat3 b c d a = forall bs cs ds. Pattern bs b -> Pattern cs c -> Pattern ds d -> Pattern (bs :++: (cs :++: ds)) a type Pat4 b c d e a = forall bs cs ds es. Pattern bs b -> Pattern cs c -> Pattern ds d -> Pattern es e -> Pattern (bs :++: (cs :++: (ds :++: es))) a type Pat5 b c d e f a = forall bs cs ds es fs. Pattern bs b -> Pattern cs c -> Pattern ds d -> Pattern es e -> Pattern fs f -> Pattern (bs :++: (cs :++: (ds :++: (es :++: fs)))) a -- | Pattern-match clauses. Typically something of the form -- --
-- pattern ->> function ---- -- Clauses can be constructed with (->>), run with -- tryMatch, and manipulated by the Monad and -- MonadPlus instances. In particular, (<|>) -- of the Alternative class is the way to list multiple cases in a -- pattern. data Clause a r -- | Constructs a Clause. (->>) :: Pattern vars a -> Fun vars r -> Clause a r -- | "Runs" a Clause. tryMatch :: a -> Clause a r -> Maybe r -- |
-- match a c = fromJust (tryMatch a c) --match :: a -> Clause a r -> r instance Functor (Clause a) instance Applicative (Clause a) instance Monad (Clause a) instance Alternative (Clause a) instance MonadPlus (Clause a) -- | Common pattern combinators. module Data.Pattern.Common -- | "Variable patterns": always succeeds, and binds the value to a -- variable. var :: Pattern (a :*: Nil) a -- | "Wildcard patterns": always succeeds. (This is written as two -- underscores.) __ :: Pat0 a -- | "And patterns". Succeeds only if both patterns succeed. -- --
-- (/\) = mk2 (a -> (a,a)) --(/\) :: Pat2 a a a -- | "Or patterns". If first pattern fails, then tries the second. (\/) :: Pattern as a -> Pattern as a -> Pattern as a -- | "View patterns": do some computation, then pattern match on the -- result. view :: (a -> b) -> Pat1 b a -- | "Partial view patterns". Synonym for mk1. tryView :: (a -> Maybe b) -> Pat1 b a -- | "Predicate pattern". mk0 but with Bool instead of -- Maybe (). Succeeds if function yields True, -- fails otherwise. -- -- Can be used with (/\) for some uses similar to pattern -- guards: -- --
-- match a $ -- left (var /\ is even) ->> id -- ||| left __ ->> const 0 -- ||| right __ ->> const 1 --is :: (a -> Bool) -> Pat0 a -- | "Constant patterns": tests for equality to the given constant. cst -- x = is (==x) cst :: (Eq a) => a -> Pat0 a -- |
-- elim = flip match ---- -- Useful for anonymous matching (or for building eliminators, -- like either). For example: -- --
-- either withLeft withRight = elim $ -- left var ->> withLeft -- <|> right var ->> withRight --elim :: Clause a r -> a -> r -- |
-- 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 " ++)
--
mmatch :: (Monad m) => m a -> Clause a (m b) -> m b
mk0 :: (a -> Maybe ()) -> Pat0 a
mk1 :: (a -> Maybe b) -> Pat1 b a
mk2 :: (a -> Maybe (b, c)) -> Pat2 b c a
mk3 :: (a -> Maybe (b, c, d)) -> Pat3 b c d a
mk4 :: (a -> Maybe (b, c, d, e)) -> Pat4 b c d e a
mk5 :: (a -> Maybe (b, c, d, e, f)) -> Pat5 b c d e f a
-- | "0-tuple pattern". A strict match on the ().
tup0 :: Pat0 ()
-- | "1-tuple pattern". Rather useless.
tup1 :: Pat1 a a
-- | "2-tuple pattern"
tup2 :: Pat2 a b (a, b)
-- | "3-tuple pattern"
tup3 :: Pat3 a b c (a, b, c)
-- | "4-tuple pattern"
tup4 :: Pat4 a b c d (a, b, c, d)
-- | "5-tuple pattern"
tup5 :: Pat5 a b c d e (a, b, c, d, e)
-- | Matches the Left of an Either.
left :: Pat1 a (Either a b)
-- | Matches the Right of an Either.
right :: Pat1 b (Either a b)
nil :: Pat0 [a]
cons :: Pat2 a [a] [a]
-- | The main import module for first-class-patterns.
--
-- As an example, the following functions, ex1 and ex2
-- are semantically equivalent:
--
-- -- ex1, ex2 :: Num a => Either a (a, a) -> a -- ex1 a = match a $ -- left (cst 4) ->> 0 -- <|> left var ->> id -- <|> right (tup2 var var) ->> (+) -- ex2 a = case a of -- Left 4 -> 0 -- Left x -> x -- Right (x,y) -> x+y ---- -- Also, when optimisation is turned on, GHC will compile them to the -- same code. module Data.Pattern -- | An associative binary operation (<|>) :: (Alternative f) => forall a. f a -> f a -> f a