131018.2 · 6a302f15b2ac2fa54f1db6e9788eb1e91a4e7501
update
reading declarations
Changes to QC/Q.hs. All files
@@ -6,6 +6,7 @@ import Control.Monad (liftM2) import Test.QuickCheck import Text.Printf (printf) +-- | A queue with O(1) `put` and amortized O(1) `get` operations. data Q a = Q { front :: [a], back :: [a] } -- corresponds to front ++ reverse back @@ -13,39 +14,50 @@ instance Show a => Show (Q a) where show (Q xs ys) = printf "(F: %s, B: %s)" (show xs) (show ys) empty :: Q a-isEmpty :: Q a -> Bool-put :: Q a -> a -> Q a-get :: Q a -> a -- defined on nonempty queue only-rest :: Q a -> Q a -- defined on nonempty queue only- empty = Q [] [] +isEmpty :: Q a -> Bool isEmpty q = null (front q) && null (back q) --- put q a = Q [] (a : back q) +-- | Adds an element to the back of the queue.+put :: Q a -> a -> Q a put q a = Q (front q) (a : back q)+-- put q a = Q [] (a : back q) -- nr's error #1 +-- | Returns an element from the top of the queue.+-- Calling @get@ on an empty queue results in a runtime error.+get :: Q a -> a -- defined on nonempty queue only get (Q [] []) = error "get from empty queue" get (Q [] as) = get (Q (reverse as) []) get (Q (a:as) _) = a +-- | Returns the given queue with the top of the queue removed.+-- Calling @rest@ on an empty queue results in a runtime error.+rest :: Q a -> Q a -- defined on nonempty queue only rest (Q [] []) = error "rest from empty queue" rest (Q [] as) = rest (Q (reverse as) []) rest (Q (a:as) bs) = Q as bs--- rest (Q (a:as) _) = Q as [] +-- rest (Q (a:as) _) = Q as [] -- nr's error #2 -- random testing +-- | QTerms represents a series of *valid* combinations of queue constructors. data QTerms = Empty | Rest QTerms | Put QTerms deriving Show --- max # of queue terms -> all valid combos -enumerate :: Int -> [QTerms]+-- | Enumerates all valid queues up to a certain number of constructor+-- applications.+enumerate :: Int -- ^ Maximum number of queue terms to enumerate.+ -> [QTerms] -- ^ All valid permutations of queue constructors. enumerate = e [] Empty 0- where e :: [QTerms] -> QTerms -> Int -> Int -> [QTerms]+ where e :: [QTerms] -- ^ Accumulated permutations.+ -> QTerms -- ^ Initial set of queue terms.+ -> Int -- ^ Number of items in the queue.+ -> Int -- ^ Number of queue terms left to generate.+ -> [QTerms] e perms _ _ 0 = perms e perms ts 0 n = e (next:perms) next 1 (n-1) where next = Put ts@@ -56,21 +68,28 @@ enumerate = e [] Empty 0 instance Arbitrary QTerms where arbitrary = elements $ enumerate 15 + -- Removing the outer most constructor application always results+ -- in a valid queue. shrink Empty = [] shrink (Rest ts) = [ts] shrink (Put ts) = [ts] +-- | Constructs a queue given a list of values and a construction of+-- a queue via `QTerms`. asQ :: [a] -> QTerms -> Q a asQ _ Empty = empty asQ as (Rest ts) = rest $ asQ as ts asQ (a:as) (Put ts) = put (asQ as ts) a +-- | Convenience function for building a queue of integers. intQ :: QTerms -> Q Int intQ = asQ [1..] +-- | Returns the last item in a queue. lastItem :: Ord a => Q a -> a lastItem q = if isEmpty (rest q) then get q else lastItem (rest q) +-- | Drains all of the items in the queue and returns the empty queue. drain :: Ord a => Q a -> Q a drain q | isEmpty q = empty