mini-egison 0.1.3 → 0.1.4
raw patch · 6 files changed
+80/−7 lines, 6 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- mini-egison.cabal +1/−1
- src/Control/Egison.hs +2/−0
- src/Control/Egison/Core.hs +6/−3
- src/Control/Egison/Match.hs +2/−0
- src/Control/Egison/Matcher.hs +11/−1
- src/Control/Egison/QQ.hs +58/−2
mini-egison.cabal view
@@ -1,7 +1,7 @@ cabal-version: 1.12 name: mini-egison-version: 0.1.3+version: 0.1.4 synopsis: Template Haskell Implementation of Egison Pattern Matching description: This package provides the pattern-matching facility that fulfills the following three criteria for practical pattern matching for non-free data types\: (i) non-linear pattern matching with backtracking; (ii) extensibility of pattern-matching algorithms; (iii) ad-hoc polymorphism of patterns. Non-free data types are data types whose data have no standard forms.
src/Control/Egison.hs view
@@ -1,3 +1,5 @@+-- | A library for user-extensible non-linear pattern matching with backtracking.+ module Control.Egison ( module Control.Egison.Core , module Control.Egison.Match
src/Control/Egison/Core.hs view
@@ -5,6 +5,8 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} +-- | Definitions of data types for patterns, matchers, match clauses, matching states, and matching atoms.+ module Control.Egison.Core ( -- * Patterns Pattern(..),@@ -34,7 +36,7 @@ --- -- | A pattern for data of a type @a@ for a matcher @m@.--- @ctx@ is an intermediate pattern-matching result and a type of a list of data bound in the left-side of the pattern.+-- @ctx@ is an intermediate pattern-matching result that is a type of a list of data bound in the left-side of the pattern. -- @vs@ is a list of types bound to the pattern variables in this pattern. data Pattern a m ctx vs where Wildcard :: Pattern a m ctx '[]@@ -46,7 +48,7 @@ -- | User-defined pattern; pattern is a function that takes a target, an intermediate pattern-matching result, and a matcher and returns a list of lists of matching atoms. Pattern :: Matcher m a => (HList ctx -> m -> a -> [MList ctx vs]) -> Pattern a m ctx vs --- | @m@ is a matcher for data of a type @a@.+-- | The @Matcher@ class is used to declare that @m@ is a matcher for data of a type @a@. class Matcher m a -- | A match clause of a match expression whose target data is @a@ and matcher is @m@.@@ -94,11 +96,12 @@ case threeMConsAssocProof atom1 atom2 atom3 of Refl -> MCons atom1 (MCons atom2 (MCons atom3 MNil)) --- | Heterogeneous list.+-- | Heterogeneous lists. data HList xs where HNil :: HList '[] HCons :: a -> HList as -> HList (a ': as) +-- | Axioms for heterogeneous lists. type family (as ::[*]) :++: (bs :: [*]) :: [*] where as :++: '[] = as '[] :++: bs = bs
src/Control/Egison/Match.hs view
@@ -2,6 +2,8 @@ {-# LANGUAGE GADTs #-} {-# LANGUAGE TypeOperators #-} +-- | Pattern-matching expressions.+ module Control.Egison.Match ( matchAll, match,
src/Control/Egison/Matcher.hs view
@@ -5,6 +5,8 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeOperators #-} +-- | Matcher definitions.+ module Control.Egison.Matcher ( -- * @Something@ matcher Something(..),@@ -29,14 +31,16 @@ import Control.Egison.QQ -- | Something built-in matcher.+-- The @Something@ matcher can handle only a pattern variable and a wildcard. data Something = Something instance Matcher Something a --- | Value patterns+-- | Value patterns. class ValuePat m a where valuePat :: (Matcher m a, Eq a) => (HList ctx -> a) -> Pattern a m ctx '[] -- | A matcher for data types that are instances of @Eq@.+-- The @Eql@ matcher can handle a pattern variable, a wildcard, and a value pattern. data Eql = Eql instance Matcher Eql a @@ -44,6 +48,7 @@ valuePat f = Pattern (\ctx _ tgt -> [MNil | f ctx == tgt]) -- | A matcher for integers.+-- The @Integer@ matcher can handle a pattern variable, a wildcard, and a value pattern. data Integer = Integer instance Integral a => Matcher Integer a @@ -68,11 +73,14 @@ -- | Patterns for collections. class CollectionPat m a where+ -- | The @nil@ pattern matches an empty collection. nil :: (Matcher m a) => Pattern a m ctx '[]+ -- | The @cons@ pattern decomposes a collection into an element and the rest elements. cons :: (Matcher m a, a ~ [a'], m ~ (f m')) => Pattern a' m' ctx xs -> Pattern a m (ctx :++: xs) ys -> Pattern a m ctx (xs :++: ys)+ -- | The @join@ pattern decomposes a collection into two collections. join :: (Matcher m a) => Pattern a m ctx xs -> Pattern a m (ctx :++: xs) ys@@ -103,6 +111,7 @@ splits (x:xs) = ([], x:xs) : [(x:ys, zs) | (ys, zs) <- splits xs] -- | a matcher for a multiset.+-- When we regard a collection as a multiset, the order of elements is ignored but the number of times an element appears in the collection is counted. newtype Multiset m = Multiset m instance (Matcher m a) => Matcher (Multiset m) [a] @@ -115,6 +124,7 @@ instance (Matcher m a) => CollectionPat (Multiset m) [a] where nil = Pattern (\_ _ tgt -> [MNil | null tgt])+ -- | The @cons@ pattern for a multiset decomposes a collection into an arbitrary element and the rest elements. cons p Wildcard = Pattern (\_ (Multiset m) tgt -> map (\x -> oneMAtom (MAtom p m x)) tgt) cons p1 p2 = Pattern (\_ (Multiset m) tgt -> map (\(x, xs) -> twoMAtoms (MAtom p1 m x) (MAtom p2 (Multiset m) xs)) (matchAll tgt (List m) [[mc| join $hs (cons $x $ts) => (x, hs ++ ts) |]]))
src/Control/Egison/QQ.hs view
@@ -1,6 +1,8 @@ {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TupleSections #-} +-- | Quasiquotation for rewriting a match clause.+ module Control.Egison.QQ ( mc, ) where@@ -16,8 +18,62 @@ import Language.Haskell.TH.Syntax import Text.Regex --+-- | A quasiquoter for rewriting a match clause.+--+-- * /Wildcards/+--+-- A match clause that contains a wildcard+--+-- > [mc| _ => "Matched" |]+--+-- is rewrited to+--+-- > MatchClause Wildcard+-- > (\HNil -> "Matched")+--+-- * /Pattern variables/+--+-- A match clause that contains a pattern variable+--+-- > [mc| $x => x |]+--+-- is rewrited to+--+-- > MatchClause (PatVar "x")+-- > (\HCons x HNil -> x)+--+-- * /Value patterns/+--+-- A match clause that contains a value pattern+--+-- > [mc| cons $x (cons $y (cons #(x + 1) (cons $z nil))) => (x, y, z) |]+--+-- is rewrited to+--+-- > MatchClause (cons (PatVar "x") (cons (PatVar "y") (cons (ValuePat (\HCons x (HCons (y HNil)) -> x + 1)) (cons (PatVar "z") nil))))+-- > (\HCons x (HCons (y (HCons z HNil))) -> (x, y, z))+--+-- * /And-patterns/+--+-- A match clause that contains an and-pattern+--+-- > [mc| (& (cons _ _) $x) => x |]+--+-- is rewrited to+--+-- > MatchClause (AndPat (cons Wildcard Wildcard) (PatVar "x"))+-- > (\HCons x HNil -> x)+--+-- * /Or-patterns/+--+-- A match clause that contains an or-pattern+--+-- > [mc| (| nil (cons _ _)) => "Matched" |]+--+-- is rewrited to+--+-- > MatchClause (OrPat nil (cons Wildcard Wildcard))+-- > (\HNil -> "Matched") mc :: QuasiQuoter mc = QuasiQuoter { quoteExp = \s -> do let [pat, exp] = splitOn "=>" s