-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtying_the_knot.hs
83 lines (69 loc) · 2.4 KB
/
tying_the_knot.hs
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
{-# LANGUAGE
StandaloneDeriving,
GADTs
#-}
-- https://wiki.haskell.org/Tying_the_Knot
data DList a where
DLNode :: Eq a => DList a -> a -> DList a -> DList a
deriving instance Eq a => Eq (DList a)
mkDList :: Eq a => [a] -> DList a
mkDList [] = error "empty list"
mkDList xs = first
-- Magic goes here
where (first, last) = go last xs first
go :: Eq a => DList a -> [a] -> DList a -> (DList a, DList a)
go prev [] next = (next, prev)
-- Contruct a segment of nodes
go prev (x:xs) next = (this, last)
where this = DLNode prev x rest
(rest, last) = go this xs next
takeF :: Integral b => b -> DList a -> [a]
takeF 0 _ = []
takeF n (DLNode _ x f) = x : takeF (n-1) f
takeB :: Integral b => b -> DList a -> [a]
takeB 0 _ = []
takeB n (DLNode b x _) = x : takeB (n-1) b
dList = mkDList "Hello, world!"
naiveDList = x
where x = 0 : y
y = 1 : x
-- Try to do either `dList == dList' or `naiveDList == naiveDList',
-- spy their memory usage, figure out where the difference comes from
-- From https://stackoverflow.com/a/9732857/8943081
-- Eq is required cause label act as node's ID
data Node a where
Node :: Eq a => {
label :: a
, adjacent :: [Node a]
} -> Node a
-- Default `show' would go on forever
--deriving instance Show a => Show (Node a)
instance (Show a) => Show (Node a) where
show (Node lbl adj) = show labels
where labels = lbl : map label adj
-- Comparing for equality seems unachievable,
-- cause Node tends to expand into an infinite tree
--deriving instance Eq a => Eq (Node a)
infiniteNode = node
where node = Node 42 [node']
node' = Node (-8) [node]
data Graph a where
Graph :: Eq a => {
nodes :: [Node a]
} -> Graph a
deriving instance Show a => Show (Graph a)
mkGraph :: Eq a => [(a, [a])] -> Graph a
mkGraph vertices = Graph $ map snd nodes
where nodes = map mkNode vertices
mkNode (label, ns) = (label, Node label $ map lookupNode ns)
lookupNode label = removeJust $ lookup label nodes
removeJust (Just a) = a
--extractNodes :: Graph a -> [Node a]
--extractNodes (Graph ns) = ns
-- 6---4---5--.
-- | | \
-- | | 1
-- | | /
-- 3---2--'
vertices = [(1,[2,5]),(2,[1,3,5]),(3,[2,4]),(4,[3,5,6]),(5,[1,2,4]),(6,[4])]
graph = mkGraph vertices