module Language.Hakaru.Evaluation.Coalesce
( coalesce )
where
import qualified Language.Hakaru.Parser.AST as U
import Language.Hakaru.Syntax.ABT
import qualified Data.Foldable as F
import Language.Hakaru.Syntax.IClasses
coalesce
:: U.AST
-> U.AST
coalesce =
cataABT_ alg
where
alg :: forall abt a. (ABT U.Term abt) => U.Term abt a -> abt '[] a
alg (U.NaryOp_ op args) = syn $ U.NaryOp_ op (coalesceNaryOp op args)
alg t = syn t
coalesceNaryOp
:: (ABT U.Term abt)
=> U.NaryOp
-> [abt '[] a]
-> [abt '[] a]
coalesceNaryOp op = F.concatMap $ \ast' ->
caseVarSyn ast' (return . var) $ \t ->
case t of
U.NaryOp_ op' args' | op == op' -> coalesceNaryOp op args'
_ -> [ast']
type M = MetaABT U.SourceSpan U.Term
preserveMetadata
:: (M xs a -> M xs a)
-> M xs a
-> M xs a
preserveMetadata f x =
case getMetadata x of
Nothing -> f x
Just s -> withMetadata s (f x)
cataABT_
:: (forall a. U.Term M a -> M '[] a)
-> (forall xs a. M xs a -> M xs a)
cataABT_ syn_ = start
where
start :: forall xs a. M xs a -> M xs a
start = preserveMetadata (loop . viewABT)
loop :: forall xs a. View (U.Term M) xs a -> M xs a
loop (Syn t) = syn_ (fmap21 start t)
loop (Var x) = var x
loop (Bind x e) = bind x (loop e)