git.iko.soy/rowtype-yoga/purescript-yoga-tree
on master help sign in
Port library guide over from my PS reference repo
8b1a67fJordan Martinez
test/Example.pursnew file+111
@@ -0,0 +1,111 @@
1+module Test.Example where
2+
3+import Prelude
4+
5+import Control.Comonad.Cofree (Cofree, head, mkCofree, tail, (:<))
6+import Control.Monad.Rec.Class (Step(..), tailRec)
7+import Data.List.Types (List(..), (:))
8+import Data.Maybe (Maybe, maybe)
9+import Data.Monoid (power)
10+import Data.Tree (Tree)
11+import Data.Tree.Zipper (fromTree, toTree, modifyValue, down, next, root)
12+import Effect (Effect)
13+import Effect.Console (log)
14+
15+-- Serves only to make this file runnable
16+main :: Effect Unit
17+main = do
18+ log "rootOnly_alias"
19+ log $ drawTree' rootOnly_alias
20+ log "----"
21+ log "rootWithLeaves"
22+ log $ drawTree' rootWithLeaves
23+ log "----"
24+ log "rootWithBranchesAndLeaves"
25+ log $ drawTree' rootWithBranchesAndLeaves
26+ log "----"
27+ log "exampleZipper"
28+ log $ maybe "" identity exampleZipper
29+
30+
31+-- These examples show how to create a Tree
32+rootOnly_mkCoFree :: Tree String
33+rootOnly_mkCoFree = mkCofree "root" Nil
34+
35+rootOnly_alias :: Tree String
36+rootOnly_alias = "root" :< Nil -- `:<` is the alias for `mkCofree`
37+
38+rootWithLeaves :: Tree String
39+rootWithLeaves =
40+ "root" :<
41+ ( ( "leaf" :< Nil )
42+ : ( "leaf" :< Nil )
43+ : ( "leaf" :< Nil )
44+ : Nil
45+ )
46+
47+rootWithBranchesAndLeaves :: Tree String
48+rootWithBranchesAndLeaves =
49+ "1" :<
50+ ( ( "1.1" :<
51+ ( ( "1.1.1" :< Nil )
52+ : ( "1.1.2" :< Nil )
53+ : Nil
54+ )
55+ )
56+ : ( "1.2" :< Nil )
57+ : ( "1.3" :<
58+ ( ( "1.3.1" :< Nil )
59+ : ( "1.3.2" :< Nil )
60+ : Nil
61+ )
62+ )
63+ : Nil
64+ )
65+
66+-- In our code, we will need to iterate through a Tree and do something
67+-- with each of its contents. Such a function has already been done
68+-- via `drawTree`, which iterates through a tree's contents
69+-- and converts it into a String, indenting them according to their respective
70+-- level:
71+-- https://github.com/dmbfm/purescript-tree/blob/v1.3.2/src/Data/Tree.purs#L21-L21
72+
73+-- The below example is a reproduction of the above code but differs from
74+-- it in that the names are more clearly defined to make it easier to see
75+-- the pattern one will follow.
76+
77+drawTree' :: Tree String -> String
78+drawTree' tree =
79+ let
80+ root = head tree
81+ children = tail tree
82+ in
83+ tailRec go {level: 1, result: root <> "\n", current: children }
84+ where
85+ go :: { level :: Int, result :: String, current :: List (Cofree List String) }
86+ -> Step { level :: Int, result :: String, current :: List (Cofree List String) } String
87+ go {level: l, result: s, current: Nil } = Done s
88+ go rec@{level: l, result: s, current: (Cons thisTree remainingTrees) } =
89+ let
90+ levelRoot = head thisTree
91+ levelChildren = tail thisTree
92+ content = (power " " l) <> levelRoot <> "\n"
93+ in Loop
94+ rec { current = remainingTrees
95+ , result = rec.result <> content <>
96+ (tailRec go { level: l + 1, result: "", current: levelChildren })
97+ }
98+
99+
100+-- Since we'll also be using the Zipper for the Tree (the `Loc` type),
101+-- we need to know how that works. For a clearer idea of what a 'Zipper' is,
102+-- see 'Design Patterns/Zipper.md':
103+exampleZipper :: Maybe String
104+exampleZipper = do
105+ let node1 = fromTree rootWithBranchesAndLeaves
106+ node1_1 <- down node1
107+ node1_1_1 <- down node1_1
108+ node1_1_2 <- next node1_1_1
109+ let node1_1_2a = modifyValue (\s -> s <> " a") node1_1_2
110+ let rootWithModification = root node1_1_2a
111+ pure $ drawTree' $ toTree rootWithModification