@@ -0,0 +1,111 @@
1+module Test.Example where
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)
15+-- Serves only to make this file runnable
19+ log $ drawTree' rootOnly_alias
22+ log $ drawTree' rootWithLeaves
24+ log "rootWithBranchesAndLeaves"
25+ log $ drawTree' rootWithBranchesAndLeaves
28+ log $ maybe "" identity exampleZipper
31+-- These examples show how to create a Tree
32+rootOnly_mkCoFree :: Tree String
33+rootOnly_mkCoFree = mkCofree "root" Nil
35+rootOnly_alias :: Tree String
36+rootOnly_alias = "root" :< Nil -- `:<` is the alias for `mkCofree`
38+rootWithLeaves :: Tree String
47+rootWithBranchesAndLeaves :: Tree String
48+rootWithBranchesAndLeaves =
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
71+-- https://github.com/dmbfm/purescript-tree/blob/v1.3.2/src/Data/Tree.purs#L21-L21
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.
77+drawTree' :: Tree String -> String
83+ tailRec go {level: 1, result: root <> "\n", current: children }
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) } =
90+ levelRoot = head thisTree
91+ levelChildren = tail thisTree
92+ content = (power " " l) <> levelRoot <> "\n"
94+ rec { current = remainingTrees
95+ , result = rec.result <> content <>
96+ (tailRec go { level: l + 1, result: "", current: levelChildren })
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
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