minstack.hs (1504B)
1 import Test.QuickCheck 2 import Control.Monad 3 4 data MinStack a = Bottom | Stack a a (MinStack a) 5 deriving (Eq, Read) 6 7 instance Show a => Show (MinStack a) where 8 show Bottom = "|" 9 show (Stack m x s) = "<" ++ show x ++ show s 10 11 push x s@(Stack m _ _) = if x < m then Stack x x s else Stack m x s 12 push x Bottom = Stack x x Bottom 13 14 pop Bottom = error "nothing there" 15 pop (Stack _ x s) = (x, s) 16 17 smin Bottom = error "nothing there" 18 smin (Stack m _ _) = m 19 20 -- Testing 21 22 fromList :: Ord a => [a] -> MinStack a 23 fromList = foldr push Bottom 24 25 toList :: MinStack a -> [a] 26 toList Bottom = [] 27 toList (Stack _ x s) = x : toList s 28 29 instance (Ord a, Arbitrary a) => Arbitrary (MinStack a) where 30 arbitrary = liftM fromList (arbitrary :: Arbitrary a => Gen [a]) 31 32 newtype NonEmptyMinStack a = NonEmptyMinStack {getValue :: MinStack a} 33 deriving (Eq, Show, Read) 34 35 instance (Ord a, Arbitrary a) => Arbitrary (NonEmptyMinStack a) where 36 arbitrary = liftM NonEmptyMinStack (arbitrary `suchThat` (/= Bottom)) 37 38 sminReturnsMinimum (NonEmptyMinStack ms) = smin ms == minimum (toList ms) 39 40 newtype LargeMinStack a = LargeMinStack {getValueOfLargeMinStack :: MinStack a} 41 deriving (Eq, Show, Read) 42 43 instance (Ord a, Arbitrary a) => Arbitrary (LargeMinStack a) where 44 arbitrary = liftM LargeMinStack (arbitrary `suchThat` ((> 1) . length . toList)) 45 46 sminUnaffectedByPopping (LargeMinStack ms) = let (x, s) = pop ms in 47 if smin ms /= smin s then x == smin ms else True 48