Tree.hs (4153B)
1 {-# OPTIONS_GHC -Wall -fno-warn-unused-top-binds #-} 2 {-# LANGUAGE TemplateHaskell #-} 3 4 module Okasaki.Tree ( 5 TreeF(..) 6 , Tree 7 , lef 8 , nod 9 10 , spy 11 12 , put 13 , pat 14 , rub 15 16 , has 17 , haz 18 19 , gas 20 ) where 21 22 import Data.Eq.Deriving (deriveEq1) 23 import Data.Fix hiding (cata, ana, hylo) 24 import Data.Functor.Foldable 25 import Data.Monoid 26 import Okasaki.Orphans () 27 import qualified Okasaki.Tree.CPS as CPS 28 import Text.Show.Deriving 29 30 data TreeF a r = 31 LeafF 32 | NodeF r !a r 33 deriving (Functor, Show) 34 35 $(deriveShow1 ''TreeF) 36 $(deriveEq1 ''TreeF) 37 38 type Tree a = Fix (TreeF a) 39 40 lef :: Tree a 41 lef = Fix LeafF 42 43 nod :: a -> Tree a -> Tree a -> Tree a 44 nod x l r = Fix (NodeF l x r) 45 46 put :: Ord a => a -> Tree a -> Tree a 47 put x = apo lag where 48 lag pin = case project pin of 49 LeafF -> NodeF (Left lef) x (Left lef) 50 NodeF l e r -> case compare x e of 51 EQ -> NodeF (Left l) e (Left r) 52 LT -> NodeF (Right l) e (Left r) 53 GT -> NodeF (Left l) e (Right r) 54 55 -- NB would be interesting to benchmark these without optimizations to 56 -- figure out the speed/memory profiles compared to the standard 57 -- versions 58 59 spy :: Ord a => a -> Tree a -> Maybe a 60 spy x = getLast . cata alg where 61 alg = \case 62 LeafF -> mempty 63 NodeF l e r 64 | x < e -> l 65 | otherwise -> Last (Just e) <> r 66 67 -- exercise 2.2 (max d + 1 comparisons) 68 haz :: Ord a => a -> Tree a -> Bool 69 haz x t = case spy x t of 70 Nothing -> False 71 Just s -> s == x 72 73 -- exercise 2.3 (no unnecessary copying) 74 pat :: Ord a => a -> Tree a -> Tree a 75 pat x t = tug id t where 76 tug k s = case project s of 77 LeafF -> k (nod x lef lef) 78 NodeF l e r -> case compare x e of 79 EQ -> t 80 LT -> tug (\a -> k (nod e a r)) l 81 GT -> tug (\a -> k (nod e l a)) r 82 83 -- exercise 2.4 (no unnecessary copying, max d + 1 comparisons) 84 rub :: Ord a => a -> Tree a -> Tree a 85 rub x t = tug Nothing id t where 86 tug c k s = case project s of 87 LeafF -> case c of 88 Nothing -> k (nod x lef lef) 89 Just a 90 | a == x -> t 91 | otherwise -> k (nod x lef lef) 92 93 NodeF l e r 94 | x < e -> tug c (\a -> k (nod e a r)) l 95 | otherwise -> tug (pure e) (\a -> k (nod e l a)) r 96 97 -- exercise 2.5a (construct balanced binary trees of depth n) 98 dap :: Ord a => a -> Int -> Tree a 99 dap x n = ana lag (n, lef) where 100 lag (j, t) 101 | j <= 0 = LeafF 102 | otherwise = 103 let s = (pred j, t) 104 in NodeF s x s 105 106 -- exercise 2.5b (construct mostly-balanced binary trees of size n) 107 sap :: Ord a => a -> Int -> Tree a 108 sap x n = ana lag (n, lef) where 109 lag (j, t) 110 | j <= 0 = LeafF 111 | odd j = 112 let s = (j `quot` 2, t) 113 in NodeF s x s 114 | otherwise = 115 let l = j `quot` 2 116 r = pred (j `quot` 2) 117 in NodeF (l, t) x (r, t) 118 119 gas :: Ord a => [a] -> Tree a 120 gas = cata $ \case 121 Nil -> lef 122 Cons h t -> put h t 123 124 dep :: Integral b => Tree a -> b 125 dep = getSum . cata alg where 126 alg = \case 127 LeafF -> mempty 128 NodeF l _ r -> 1 <> max l r 129 130 wyt :: Integral b => Tree a -> b 131 wyt = getSum . cata alg where 132 alg = \case 133 LeafF -> mempty 134 NodeF l _ r -> 1 <> l <> r 135 136 has :: Ord a => a -> Tree a -> Bool 137 has x = cata $ \case 138 LeafF -> False 139 NodeF l e r -> case compare x e of 140 EQ -> True 141 LT -> l 142 GT -> r 143 144 ver :: CPS.Tree a -> Tree a 145 ver = ana lag where 146 lag (project -> CPS.TreeF c) = c LeafF NodeF 147 148 rev :: Tree a -> CPS.Tree a 149 rev = ana lag where 150 lag pin = case project pin of 151 LeafF -> CPS.lefF 152 NodeF l e r -> CPS.nodF e l r 153 154 test0 :: Num a => Tree a 155 test0 = nod 1 lef lef 156 157 -- 1 158 -- | \ 159 -- L L 160 161 test1 :: Num a => Tree a 162 test1 = nod 2 (nod 1 lef lef) (nod 3 lef lef) 163 164 -- 2 165 -- | \ 166 -- 1 3 167 -- | \ | \ 168 -- L L L L 169 170 test2 :: (Ord a, Num a) => Tree a 171 test2 = put 0 test1 172 173 -- 2 174 -- | \ 175 -- 1 3 176 -- | \ | \ 177 -- 0 L L L 178 -- | \ 179 -- L L 180 181 test3 :: (Ord a, Num a) => Tree a 182 test3 = put 5 test1 183 184 -- 2 185 -- | \ 186 -- 1 3 187 -- | \ | \ 188 -- L L L 5 189 -- | \ 190 -- L L 191 192 test4 :: (Ord a, Num a) => Tree a 193 test4 = put 4 test3 194 195 -- 2 196 -- | \ 197 -- 1 3 198 -- | \ | \ 199 -- L L L 5 200 -- | \ 201 -- 4 L 202 -- | \ 203 -- L L 204