public
Description: Code for blog entries
Homepage: http://splonderzoek.blogspot.com/
Clone URL: git://github.com/spl/splonderzoek.git
splonderzoek / IncrementalAttributes2Inherited.hs
100644 60 lines (45 sloc) 1.446 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
{-
This is the second source file for the splonderzoek blog entry dated 2008-03-31:
 
http://splonderzoek.blogspot.com/2009/03/incremental-attributes.html
-}
 
module IncrementalAttributes2Inherited where
 
data Tree a i
  = Tip i
  | Bin a (Tree a i) (Tree a i) i
  deriving Show
 
data Alg a i
  = Alg { itip :: i -> i, ibin :: a -> i -> i }
 
result :: Tree a i -> i
result (Tip i) = i
result (Bin _ _ _ i) = i
 
tip :: Alg a i -> i -> Tree a i
tip alg i = Tip (itip alg i)
 
bin :: Alg a i -> i -> a -> Tree a i -> Tree a i -> Tree a i
bin alg i x lt rt = Bin x (update i lt) (update i rt) i
  where
    update i' t =
      case t of
        Tip _ ->
          tip alg i'
        Bin x lt rt _ ->
          let s = ibin alg x i' in
          Bin x (update s lt) (update s lt) s
 
empty :: (Ord a) => Alg a i -> i -> Tree a i
empty = tip
 
singleton :: (Ord a) => Alg a i -> i -> a -> Tree a i
singleton alg i x = bin alg i x (tip alg i) (tip alg i)
 
insert :: (Ord a) => Alg a i -> a -> Tree a i -> Tree a i
insert alg x t =
  case t of
    Tip i ->
      singleton alg i x
    Bin y lt rt i ->
      case compare x y of
        LT -> bin alg i y (insert alg x lt) rt
        GT -> bin alg i y lt (insert alg x rt)
        EQ -> bin alg i x lt rt
 
fromList :: (Ord a) => Alg a i -> i -> [a] -> Tree a i
fromList alg i = foldr (insert alg) (empty alg i)
 
depthAlg :: Alg a Int
depthAlg = Alg (+1) (const (+1))
 
t1 = fromList depthAlg 0 "azbycx"