module Language.Egison.Syntax.Pattern.Combinator
( unAnnotate
, foldExpr
, mapName
, mapVarName
, mapValueExpr
, variables
)
where
import Control.Applicative ( Alternative(..) )
import Data.Foldable ( asum )
import Data.Functor.Foldable ( cata
, embed
)
import Control.Comonad.Cofree ( Cofree )
import Control.Comonad.Trans.Cofree ( CofreeF(..) )
import Language.Egison.Syntax.Pattern.Expr
( Expr(..) )
import Language.Egison.Syntax.Pattern.Base
( ExprF(..) )
unAnnotate :: Cofree (ExprF n v e) a -> Expr n v e
unAnnotate = cata go where go (_ :< x) = embed x
foldExpr :: (ExprF n v e a -> a) -> Expr n v e -> a
foldExpr = cata
mapName :: (n -> n') -> Expr n v e -> Expr n' v e
mapName f = cata go
where
go (InfixF n a b ) = Infix (f n) a b
go (PatternF n ps) = Pattern (f n) ps
go WildcardF = Wildcard
go (VariableF n) = Variable n
go (ValueF e) = Value e
go (PredicateF e) = Predicate e
go (AndF p1 p2 ) = And p1 p2
go (OrF p1 p2 ) = Or p1 p2
go (NotF p1 ) = Not p1
mapVarName :: (v -> v') -> Expr n v e -> Expr n v' e
mapVarName f = cata go
where
go (VariableF v) = Variable (f v)
go WildcardF = Wildcard
go (ValueF e ) = Value e
go (PredicateF e ) = Predicate e
go (AndF p1 p2 ) = And p1 p2
go (OrF p1 p2 ) = Or p1 p2
go (NotF p1 ) = Not p1
go (InfixF n a b ) = Infix n a b
go (PatternF n ps) = Pattern n ps
mapValueExpr :: (e -> e') -> Expr n v e -> Expr n v e'
mapValueExpr f = cata go
where
go (ValueF e) = Value (f e)
go (PredicateF e) = Predicate (f e)
go WildcardF = Wildcard
go (VariableF n ) = Variable n
go (InfixF n p1 p2) = Infix n p1 p2
go (PatternF n ps) = Pattern n ps
go (AndF p1 p2) = And p1 p2
go (OrF p1 p2) = Or p1 p2
go (NotF p1 ) = Not p1
variables :: Alternative f => Expr n v e -> f v
variables = cata go
where
go (VariableF n) = pure n
go WildcardF = empty
go (ValueF _ ) = empty
go (PredicateF _ ) = empty
go (AndF p1 p2 ) = p1 <|> p2
go (OrF p1 p2 ) = p1 <|> p2
go (NotF p1 ) = p1
go (InfixF _ a b ) = a <|> b
go (PatternF _ ps) = asum ps