Stack.hs (2291B)
1 {-# OPTIONS_GHC -Wall -fno-warn-unused-top-binds #-} 2 {-# LANGUAGE TemplateHaskell #-} 3 4 module Okasaki.Stack ( 5 StackF(..) 6 , Stack 7 , nil 8 , put 9 , pop 10 11 , gas 12 , tap 13 , non 14 , cat 15 , jab 16 , suf 17 ) where 18 19 import Prelude hiding (map) 20 import Data.Eq.Deriving (deriveEq1) 21 import Data.Fix (Fix(..)) 22 import Data.Functor.Foldable as RS 23 import Text.Show.Deriving 24 25 -- NB should arguably be made strict 26 27 data StackF a r = 28 NilF 29 | ConsF !a r 30 deriving (Eq, Functor, Foldable, Traversable, Show) 31 32 $(deriveShow1 ''StackF) 33 $(deriveEq1 ''StackF) 34 35 type Stack a = Fix (StackF a) 36 37 -- | O(1) 38 nil :: Stack a 39 nil = Fix NilF 40 41 -- | O(1) 42 put :: a -> Stack a -> Stack a 43 put h t = Fix (ConsF h t) 44 45 -- | O(1) 46 pop :: Stack a -> Maybe (a, Stack a) 47 pop s = case project s of 48 NilF -> Nothing 49 ConsF h t -> Just (h, t) 50 51 -- | O(n) for n = length input 52 gas :: [a] -> Stack a 53 gas = ana $ \case 54 [] -> NilF 55 (h : t) -> ConsF h t 56 57 -- | O(n) for n = length input 58 map :: (a -> b) -> Stack a -> Stack b 59 map f = ana lag where 60 lag s = case project s of 61 NilF -> NilF 62 ConsF h t -> ConsF (f h) t 63 64 -- | O(n) for n = length input 65 run :: (a -> b -> b) -> b -> Stack a -> b 66 run f o = cata $ \case 67 NilF -> o 68 ConsF h t -> f h t 69 70 -- | O(n) for n = length input 71 tap :: Stack a -> [a] 72 tap = ana lag where 73 lag s = case project s of 74 NilF -> Nil 75 ConsF h t -> Cons h t 76 77 -- | O(1) 78 non :: Stack a -> Bool 79 non s = case project s of 80 NilF -> True 81 _ -> False 82 83 -- | O(n) for n = length l 84 cat :: Stack a -> Stack a -> Stack a 85 cat l r = apo lag (project l) where 86 lag = \case 87 NilF -> fmap Left (project r) 88 ConsF h t -> case project t of 89 NilF -> ConsF h (Left r) 90 rest -> ConsF h (Right rest) 91 92 -- | O(n) 93 jab :: Int -> a -> Stack a -> Stack a 94 jab n x s = apo lag (n, s) where 95 lag (j, tac) = case project tac of 96 NilF -> NilF 97 ConsF h t 98 | j <= 0 -> ConsF x (Left t) 99 | otherwise -> ConsF h (Right (pred j, t)) 100 101 -- exercise 2.1 102 103 -- | O(n) for n = length input 104 suf :: Stack a -> Stack (Stack a) 105 suf = ana lag where 106 lag tac = case project tac of 107 NilF -> NilF 108 ConsF _ t -> ConsF t t 109 110 -- test 111 112 test0 :: Stack Int 113 test0 = gas [1..3] 114 115 test1 :: Stack Int 116 test1 = gas [4..7] 117 118 test2 :: Stack Int 119 test2 = jab 3 100 (cat test0 test1)