-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathP73.hs
More file actions
63 lines (52 loc) · 1.8 KB
/
P73.hs
File metadata and controls
63 lines (52 loc) · 1.8 KB
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
module MultiwayTree.P73 where
import Control.Applicative ((<|>))
import qualified Control.Applicative as A
import DList (DList)
import qualified DList as D
import MultiwayTree.MultiwayTree (Tree (..))
import Parser (Parser (..))
import qualified Parser as P
{-
Problem 73: (**) Lisp-like multiway tree representation.
An s-expression is commonly represented as a list of items between parentheses.
In particular, s-expressions can be nested, e.g., (a b (c d) e (f g)).
It is used by programming languages such as Lisp and Scheme.
A possible way to represent a multiway tree with an s-expression is for the
first element in a list to represent the root of the tree, and the rest of
the elements in the list would be its children.
As a special case, a multiway tree with no children is represented without parentheses.
Write a function which will return this s-expression representation of a
multiway tree as a string.
As a second, even more interesting exercise try to write the inverse conversion.
-}
treeToLisp :: Tree Char -> String
treeToLisp = tail . D.toList . go D.empty
where
go :: DList Char -> Tree Char -> DList Char
go acc (Node x []) = acc D.++ D.singleton ' ' D.++ D.singleton x
go acc (Node x forest) =
acc
D.++ D.singleton ' '
D.++ D.singleton '('
D.++ D.singleton x
D.++ xs
D.++ D.singleton ')'
where
xs = foldl go D.empty forest
type TreeParser = Parser (Tree Char)
branch :: TreeParser
branch = do
x <- P.open *> P.letter <* P.space
forest <- A.some mwTree <* P.close
return $ Node x forest
singleton :: TreeParser
singleton = do
x <- P.letter
return $ Node x []
mwTree :: TreeParser
mwTree = do
tree <- branch <|> singleton
P.space
return tree
lispToTree :: String -> Tree Char
lispToTree = fst . head . P.parse mwTree