-
Notifications
You must be signed in to change notification settings - Fork 0
/
Rec.hs
66 lines (50 loc) · 1.81 KB
/
Rec.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
{-|
Module : Language.Go.Rec
Description : Golang recursion schemes
Maintainer : [email protected]
Stability : experimental
Recursion scheme combinators for Go abstract syntax.
-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
module Language.Go.Rec where
import Data.Functor.Const
import Data.Functor.Product
import Data.Parameterized.TraversableFC
import Language.Go.Types
newtype Fix f i = In (f (Fix f) i)
out :: Fix f i -> f (Fix f) i
out (In f) = f
cata :: FunctorFC f
=> (forall i. f a i -> a i)
-> (forall i. Fix f i -> a i)
cata phi = phi . fmapFC (cata phi) . out
cata' :: FunctorFC f
=> (forall i. f (Const a) i -> a)
-> (forall i. Fix f i -> a)
cata' phi = getConst . cata (Const . phi)
cataM :: (TraversableFC f, Monad m)
=> (forall i. f a i -> m (a i))
-> (forall i. Fix f i -> m (a i))
cataM phi (In x) = traverseFC (cataM phi) x >>= phi
cataM' :: (TraversableFC f, Monad m)
=> (forall i. f (Const a) i -> m a)
-> (forall i. Fix f i -> m a)
cataM' phi = (getConst <$>) . cataM ((Const <$>) . phi)
para :: FunctorFC f
=> (forall i. f (Product (Fix f) a) i -> a i)
-> (forall i. Fix f i -> a i)
para phi = phi . fmapFC (\x -> Pair x (para phi x)) . out
paraM :: (TraversableFC f, Monad m)
=> (forall i. f (Product (Fix f) a) i -> m (a i))
-> (forall i. Fix f i -> m (a i))
paraM phi (In x) = traverseFC (\y -> Pair y <$> paraM phi y) x >>= phi
----------------------------------------------------------------------
-- Utility functions
pairM :: Applicative f => f a -> f b -> f (a, b)
pairM x y = (,) <$> x <*> y
proj1 :: forall f g (a :: NodeType). Product f g a -> f a
proj1 (Pair x _y) = x
proj2 :: forall f g (a :: NodeType). Product f g a -> g a
proj2 (Pair _x y) = y