6 | import Language.Reflection
7 | import Derive.Prelude
11 | %language ElabReflection
23 | namespace BinaryTrees
26 | data BinTree : (leafType : Type) -> (nodeType : Type) -> Type where
28 | BinTree leafType nodeType
30 | BinTree leafType nodeType ->
31 | BinTree leafType nodeType ->
32 | BinTree leafType nodeType
34 | %runElab derive "BinTree" [Eq, Show]
35 | %name BinTree
bt, bt', bt''
48 | Bifunctor BinTree where
49 | bimap f g (Leaf x) = Leaf (f x)
50 | bimap f g (Node n leftTree rightTree)
51 | = Node (g n) (bimap f g leftTree) (bimap f g rightTree)
53 | namespace BinTreeSame
56 | BinTreeSame : (content : Type) -> Type
57 | BinTreeSame content = BinTree content content
60 | Functor BinTreeSame where
61 | map f (Leaf x) = Leaf (f x)
62 | map f (Node x leftTree rightTree) = Node (f x)
63 | (map {f=BinTreeSame} f leftTree)
64 | (map {f=BinTreeSame} f rightTree)
71 | liftA2BinTreeSame : BinTreeSame a -> BinTreeSame b -> BinTreeSame (a, b)
72 | liftA2BinTreeSame (Leaf a) (Leaf b) = Leaf (a, b)
73 | liftA2BinTreeSame l@(Leaf a) (Node b ltb rtb)
74 | = Node (a, b) (liftA2BinTreeSame l ltb) (liftA2BinTreeSame l rtb)
75 | liftA2BinTreeSame (Node a lta rta) l@(Leaf b)
76 | = Node (a, b) (liftA2BinTreeSame lta l) (liftA2BinTreeSame rta l)
77 | liftA2BinTreeSame (Node a lta rta) (Node b ltb rtb)
78 | = Node (a, b) (liftA2BinTreeSame lta ltb) (liftA2BinTreeSame rta rtb)
82 | Applicative BinTreeSame where
89 | fs <*> xs = map {f=BinTreeSame} (uncurry ($)) $
liftA2BinTreeSame fs xs
93 | namespace LeavesOnly
95 | BinTreeLeaf : (leafType : Type) -> Type
96 | BinTreeLeaf leafType = BinTree leafType ()
100 | Node' : BinTree l () -> BinTree l () -> BinTree l ()
104 | Functor BinTreeLeaf where
105 | map f (Leaf x) = Leaf (f x)
106 | map f (Node x leftTree rightTree) = Node x
107 | (map {f=BinTreeLeaf} f leftTree)
108 | (map {f=BinTreeLeaf} f rightTree)
111 | liftA2BinTreeLeaf : BinTreeLeaf a -> BinTreeLeaf b -> BinTreeLeaf (a, b)
112 | liftA2BinTreeLeaf (Leaf a) (Leaf b)
114 | liftA2BinTreeLeaf l@(Leaf x) (Node () z w)
115 | = Node () (liftA2BinTreeLeaf l z) (liftA2BinTreeLeaf l w)
116 | liftA2BinTreeLeaf (Node () z w) (Leaf x)
117 | = Node () (liftA2BinTreeLeaf z (Leaf x)) (liftA2BinTreeLeaf w (Leaf x))
118 | liftA2BinTreeLeaf (Node () y z) (Node () v s)
119 | = Node () (liftA2BinTreeLeaf y v) (liftA2BinTreeLeaf z s)
122 | Applicative BinTreeLeaf where
124 | fs <*> xs = map {f=BinTreeLeaf} (uncurry ($)) $
liftA2BinTreeLeaf fs xs
131 | Foldable BinTreeLeaf where
132 | foldr f z (Leaf leaf) = f leaf z
133 | foldr f z (Node () leftTree rightTree) =
136 | let rightResult = foldr {t=BinTreeLeaf} f z rightTree
137 | in foldr {t=BinTreeLeaf} f rightResult leftTree
139 | namespace NodesOnly
141 | BinTreeNode : (nodeType : Type) -> Type
142 | BinTreeNode nodeType = BinTree () nodeType
146 | Leaf' : BinTree () n
150 | Functor BinTreeNode where
151 | map f (Leaf leaf) = Leaf leaf
152 | map f (Node node leftTree rightTree)
153 | = Node (f node) (map {f=BinTreeNode} f leftTree) (map {f=BinTreeNode} f rightTree)
161 | namespace Traversals
170 | MyTree : BinTree Int Int
171 | MyTree = Node 4 (Node 2 (Leaf 1) (Leaf 3)) (Leaf 5)
174 | inorder : BinTree a b -> List (Either a b)
175 | inorder (Leaf leaf) = [Left leaf]
176 | inorder (Node node leftTree rightTree) =
177 | inorder leftTree ++ [Right node] ++ inorder rightTree
180 | Traversals.inorder MyTree = [Left 1, Right 2, Left 3, Right 4, Left 5]
184 | preorder : BinTree a b -> List (Either a b)
185 | preorder (Leaf leaf) = [Left leaf]
186 | preorder (Node node leftTree rightTree) =
187 | [Right node] ++ preorder leftTree ++ preorder rightTree
189 | testPreorder : Traversals.preorder MyTree
190 | = [Right 4, Right 2, Left 1, Left 3, Left 5]
191 | testPreorder = Refl
194 | postorder : BinTree a b -> List (Either a b)
195 | postorder (Leaf leaf) = [Left leaf]
196 | postorder (Node node leftTree rightTree)
197 | = postorder leftTree ++ postorder rightTree ++ [Right node]
199 | testPostorder : Traversals.postorder MyTree
200 | = [Left 1, Left 3, Right 2, Left 5, Right 4]
201 | testPostorder = Refl
204 | fromEitherUnit : List (Either a ()) -> List a
205 | fromEitherUnit [] = []
206 | fromEitherUnit ((Left a) :: xs) = a :: fromEitherUnit xs
207 | fromEitherUnit ((Right ()) :: xs) = fromEitherUnit xs
210 | fromUnitEither : List (Either () a) -> List a
211 | fromUnitEither [] = []
212 | fromUnitEither ((Right a) :: xs) = a :: fromUnitEither xs
213 | fromUnitEither ((Left ()) :: xs) = fromUnitEither xs
217 | traverseBinTreeLeaf : BinTreeLeaf a -> List a
218 | traverseBinTreeLeaf bt = fromEitherUnit (inorder bt)
222 | inorderNode : BinTreeNode a -> List a
223 | inorderNode bt = fromUnitEither (inorder bt)
226 | preorderNode : BinTreeNode a -> List a
227 | preorderNode bt = fromUnitEither (preorder bt)
230 | postorderNode : BinTreeNode a -> List a
231 | postorderNode bt = fromUnitEither (postorder bt)
235 | namespace RoseTrees
239 | data RoseTree : (leafType : Type) -> (nodeType : Type) -> Type where
241 | RoseTree leafType nodeType
243 | List (RoseTree leafType nodeType) ->
244 | RoseTree leafType nodeType
246 | %runElab derive "RoseTree" [Eq, Show]
247 | %name RoseTree
rt, rt', rt''
250 | namespace RoseTreeSame
252 | RoseTreeSame : (content : Type) -> Type
253 | RoseTreeSame content = RoseTree content content
256 | Functor RoseTreeSame where
257 | map f (Leaf x) = Leaf (f x)
258 | map f (Node x subTrees) = Node (f x) (map {f=RoseTreeSame} f <$> subTrees)
261 | liftA2RoseTreeSame : RoseTreeSame a -> RoseTreeSame b -> RoseTreeSame (a, b)
262 | liftA2RoseTreeSame (Leaf a) (Leaf b) = Leaf (a, b)
263 | liftA2RoseTreeSame l@(Leaf a) (Node b subTreesb)
264 | = Node (a, b) ((\st => liftA2RoseTreeSame l st) <$> subTreesb)
265 | liftA2RoseTreeSame (Node a subTreesa) l@(Leaf b)
266 | = Node (a, b) ((\st => liftA2RoseTreeSame st l) <$> subTreesa)
268 | liftA2RoseTreeSame (Node a subTreesa) (Node b subTreesb)
269 | = Node (a, b) ((uncurry liftA2RoseTreeSame) <$> (listZip subTreesa subTreesb))
273 | Applicative RoseTreeSame where
275 | fs <*> xs = map {f=RoseTreeSame} (uncurry ($)) $
liftA2RoseTreeSame fs xs