2 | import Language.Reflection
3 | import Derive.Prelude
7 | %language ElabReflection
19 | namespace BinaryTrees
22 | data BinTree : (leafType : Type) -> (nodeType : Type) -> Type where
24 | BinTree leafType nodeType
26 | BinTree leafType nodeType ->
27 | BinTree leafType nodeType ->
28 | BinTree leafType nodeType
30 | %runElab derive "BinTree" [Eq, Show]
31 | %name BinTree
bt, bt', bt''
44 | Bifunctor BinTree where
45 | bimap f g (Leaf x) = Leaf (f x)
46 | bimap f g (Node n leftTree rightTree)
47 | = Node (g n) (bimap f g leftTree) (bimap f g rightTree)
49 | namespace BinTreeSame
52 | BinTreeSame : (content : Type) -> Type
53 | BinTreeSame content = BinTree content content
56 | Functor BinTreeSame where
57 | map f (Leaf x) = Leaf (f x)
58 | map f (Node x leftTree rightTree) = Node (f x)
59 | (map {f=BinTreeSame} f leftTree)
60 | (map {f=BinTreeSame} f rightTree)
67 | liftA2BinTreeSame : BinTreeSame a -> BinTreeSame b -> BinTreeSame (a, b)
68 | liftA2BinTreeSame (Leaf a) (Leaf b) = Leaf (a, b)
69 | liftA2BinTreeSame l@(Leaf a) (Node b ltb rtb)
70 | = Node (a, b) (liftA2BinTreeSame l ltb) (liftA2BinTreeSame l rtb)
71 | liftA2BinTreeSame (Node a lta rta) l@(Leaf b)
72 | = Node (a, b) (liftA2BinTreeSame lta l) (liftA2BinTreeSame rta l)
73 | liftA2BinTreeSame (Node a lta rta) (Node b ltb rtb)
74 | = Node (a, b) (liftA2BinTreeSame lta ltb) (liftA2BinTreeSame rta rtb)
78 | Applicative BinTreeSame where
85 | fs <*> xs = map {f=BinTreeSame} (uncurry ($)) $
liftA2BinTreeSame fs xs
89 | namespace LeavesOnly
91 | BinTreeLeaf : (leafType : Type) -> Type
92 | BinTreeLeaf leafType = BinTree leafType ()
96 | Node' : BinTree l () -> BinTree l () -> BinTree l ()
100 | Functor BinTreeLeaf where
101 | map f (Leaf x) = Leaf (f x)
102 | map f (Node x leftTree rightTree) = Node x
103 | (map {f=BinTreeLeaf} f leftTree)
104 | (map {f=BinTreeLeaf} f rightTree)
107 | liftA2BinTreeLeaf : BinTreeLeaf a -> BinTreeLeaf b -> BinTreeLeaf (a, b)
108 | liftA2BinTreeLeaf (Leaf a) (Leaf b)
110 | liftA2BinTreeLeaf l@(Leaf x) (Node () z w)
111 | = Node () (liftA2BinTreeLeaf l z) (liftA2BinTreeLeaf l w)
112 | liftA2BinTreeLeaf (Node () z w) (Leaf x)
113 | = Node () (liftA2BinTreeLeaf z (Leaf x)) (liftA2BinTreeLeaf w (Leaf x))
114 | liftA2BinTreeLeaf (Node () y z) (Node () v s)
115 | = Node () (liftA2BinTreeLeaf y v) (liftA2BinTreeLeaf z s)
118 | Applicative BinTreeLeaf where
120 | fs <*> xs = map {f=BinTreeLeaf} (uncurry ($)) $
liftA2BinTreeLeaf fs xs
127 | Foldable BinTreeLeaf where
128 | foldr f z (Leaf leaf) = f leaf z
129 | foldr f z (Node () leftTree rightTree) =
132 | let rightResult = foldr {t=BinTreeLeaf} f z rightTree
133 | in foldr {t=BinTreeLeaf} f rightResult leftTree
135 | namespace NodesOnly
137 | BinTreeNode : (nodeType : Type) -> Type
138 | BinTreeNode nodeType = BinTree () nodeType
142 | Leaf' : BinTree () n
146 | Functor BinTreeNode where
147 | map f (Leaf leaf) = Leaf leaf
148 | map f (Node node leftTree rightTree)
149 | = Node (f node) (map {f=BinTreeNode} f leftTree) (map {f=BinTreeNode} f rightTree)
157 | namespace Traversals
166 | MyTree : BinTree Int Int
167 | MyTree = Node 4 (Node 2 (Leaf 1) (Leaf 3)) (Leaf 5)
170 | inorder : BinTree a b -> List (Either a b)
171 | inorder (Leaf leaf) = [Left leaf]
172 | inorder (Node node leftTree rightTree) =
173 | inorder leftTree ++ [Right node] ++ inorder rightTree
176 | Traversals.inorder MyTree = [Left 1, Right 2, Left 3, Right 4, Left 5]
180 | preorder : BinTree a b -> List (Either a b)
181 | preorder (Leaf leaf) = [Left leaf]
182 | preorder (Node node leftTree rightTree) =
183 | [Right node] ++ preorder leftTree ++ preorder rightTree
185 | testPreorder : Traversals.preorder MyTree
186 | = [Right 4, Right 2, Left 1, Left 3, Left 5]
187 | testPreorder = Refl
190 | postorder : BinTree a b -> List (Either a b)
191 | postorder (Leaf leaf) = [Left leaf]
192 | postorder (Node node leftTree rightTree)
193 | = postorder leftTree ++ postorder rightTree ++ [Right node]
195 | testPostorder : Traversals.postorder MyTree
196 | = [Left 1, Left 3, Right 2, Left 5, Right 4]
197 | testPostorder = Refl
200 | fromEitherUnit : List (Either a ()) -> List a
201 | fromEitherUnit [] = []
202 | fromEitherUnit ((Left a) :: xs) = a :: fromEitherUnit xs
203 | fromEitherUnit ((Right ()) :: xs) = fromEitherUnit xs
206 | fromUnitEither : List (Either () a) -> List a
207 | fromUnitEither [] = []
208 | fromUnitEither ((Right a) :: xs) = a :: fromUnitEither xs
209 | fromUnitEither ((Left ()) :: xs) = fromUnitEither xs
213 | traverseBinTreeLeaf : BinTreeLeaf a -> List a
214 | traverseBinTreeLeaf bt = fromEitherUnit (inorder bt)
218 | inorderNode : BinTreeNode a -> List a
219 | inorderNode bt = fromUnitEither (inorder bt)
222 | preorderNode : BinTreeNode a -> List a
223 | preorderNode bt = fromUnitEither (preorder bt)
226 | postorderNode : BinTreeNode a -> List a
227 | postorderNode bt = fromUnitEither (postorder bt)
231 | namespace RoseTrees
235 | data RoseTree : (leafType : Type) -> (nodeType : Type) -> Type where
237 | RoseTree leafType nodeType
239 | List (RoseTree leafType nodeType) ->
240 | RoseTree leafType nodeType
242 | %runElab derive "RoseTree" [Eq, Show]
243 | %name RoseTree
rt, rt', rt''
246 | namespace RoseTreeSame
248 | RoseTreeSame : (content : Type) -> Type
249 | RoseTreeSame content = RoseTree content content
252 | Functor RoseTreeSame where
253 | map f (Leaf x) = Leaf (f x)
254 | map f (Node x subTrees) = Node (f x) (map {f=RoseTreeSame} f <$> subTrees)
257 | liftA2RoseTreeSame : RoseTreeSame a -> RoseTreeSame b -> RoseTreeSame (a, b)
258 | liftA2RoseTreeSame (Leaf a) (Leaf b) = Leaf (a, b)
259 | liftA2RoseTreeSame l@(Leaf a) (Node b subTreesb)
260 | = Node (a, b) ((\st => liftA2RoseTreeSame l st) <$> subTreesb)
261 | liftA2RoseTreeSame (Node a subTreesa) l@(Leaf b)
262 | = Node (a, b) ((\st => liftA2RoseTreeSame st l) <$> subTreesa)
264 | liftA2RoseTreeSame (Node a subTreesa) (Node b subTreesb)
265 | = Node (a, b) ((uncurry liftA2RoseTreeSame) <$> (listZip subTreesa subTreesb))
269 | Applicative RoseTreeSame where
271 | fs <*> xs = map {f=RoseTreeSame} (uncurry ($)) $
liftA2RoseTreeSame fs xs
275 | {a : Type} -> Display a => Display (RoseTreeSame a) where
276 | display (Leaf x) = display x
277 | display (Node x rts)
278 | = let (
xh ** xw ** dx)
= display x