-------------------------------------------------------------------------
--  
--     StoreTest.hs
--  
--         An abstract data type of stores of integers, together with 
--         QuickCheck generator.
--                                  
--         (c) Addison-Wesley, 1996-2011.                   
--  
-------------------------------------------------------------------------


module StoreTest 
   ( Store, 
     initial,     -- Store
     value,       -- Store -> Var -> Integer
     update       -- Store -> Var -> Integer -> Store
    ) where

import Test.QuickCheck

-- Var is the type of variables.                    

type Var = Char

-- The implementation is given by a newtype declaration, with one
-- constructor, taking an argument of type [ (Integer,Var) ].

data Store = Store [ (Integer,Var) ] 

instance Eq Store where 
  (Store [(Integer, Var)]
sto1) == :: Store -> Store -> Bool
== (Store [(Integer, Var)]
sto2) = ([(Integer, Var)]
sto1 [(Integer, Var)] -> [(Integer, Var)] -> Bool
forall a. Eq a => a -> a -> Bool
== [(Integer, Var)]
sto2)                 

instance Show Store where
  showsPrec :: Int -> Store -> ShowS
showsPrec Int
n (Store [(Integer, Var)]
sto) = Int -> [(Integer, Var)] -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
n [(Integer, Var)]
sto                 
--  
initial :: Store 

initial :: Store
initial = [(Integer, Var)] -> Store
Store []

value  :: Store -> Var -> Integer

value :: Store -> Var -> Integer
value (Store []) Var
v         = Integer
0
value (Store ((Integer
n,Var
w):[(Integer, Var)]
sto)) Var
v 
  | Var
vVar -> Var -> Bool
forall a. Eq a => a -> a -> Bool
==Var
w            = Integer
n
  | Bool
otherwise       = Store -> Var -> Integer
value ([(Integer, Var)] -> Store
Store [(Integer, Var)]
sto) Var
v

update  :: Store -> Var -> Integer -> Store

update :: Store -> Var -> Integer -> Store
update (Store [(Integer, Var)]
sto) Var
v Integer
n = [(Integer, Var)] -> Store
Store ((Integer
n,Var
v)(Integer, Var) -> [(Integer, Var)] -> [(Integer, Var)]
forall a. a -> [a] -> [a]
:[(Integer, Var)]
sto)

-- QuickCheck stuff

instance Arbitrary Store where
    arbitrary :: Gen Store
arbitrary = do
      [(Integer, Var)]
list <- Gen (Integer, Var) -> Gen [(Integer, Var)]
forall a. Gen a -> Gen [a]
listOf Gen (Integer, Var)
element
      Store -> Gen Store
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return (Store -> Gen Store) -> Store -> Gen Store
forall a b. (a -> b) -> a -> b
$ [(Integer, Var)] -> Store
Store [(Integer, Var)]
list
                where
                  element :: Gen (Integer, Var)
element =
                      do
                        Integer
n <- Gen Integer
forall a. Arbitrary a => Gen a
arbitrary
                        Var
v <- String -> Gen Var
forall a. HasCallStack => [a] -> Gen a
elements [Var
'a'..Var
'z']
                        (Integer, Var) -> Gen (Integer, Var)
forall a. a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer
n,Var
v)