Files

227 lines
6.6 KiB
Haskell

{-# LANGUAGE TemplateHaskell, ScopedTypeVariables, StandaloneDeriving #-}
module Set12Test where
import Mooc.Test
import Mooc.Th
import Data.List
import Data.Monoid
import Test.QuickCheck hiding (Result,Fun,Failure)
import Set12
main = score tests
tests = [(1,"incrementAll",[ex1_list, ex1_just, ex1_nothing])
,(2,"fmap23",[ex2_fmap2_examples, ex2_fmap3_examples])
,(3,"Functor Result",[ex3_num, ex3_empties])
,(4,"Functor List",[ex4_num, ex4_bool])
,(5,"Functor TwoList",[ex5_num, ex5_bool])
,(6,"count",[ex6_list, ex6_maybe])
,(7,"inBoth",[ex7_list, ex7_maybe])
,(8,"Foldable List",[ex8_bool, ex8_num])
,(9,"Foldable TwoList",[ex9_bool, ex9_num])
,(10,"Fun",[ex10_1, ex10_2])
,(11,"Foldable Tree",[ex11_fmap_even, ex11_fmap_plus, ex11_sumTree_int, ex11_sumTree_list])]
-- -- -- -- -- --
ex1_list =
forAll_ $ \(xs::[Int]) ->
$(testing [|incrementAll xs|]) (?== map (+1) xs)
ex1_just =
forAll_ $ \(i::Int) ->
$(testing [|incrementAll (Just i)|]) (?== Just (i+1))
ex1_nothing = $(testing [|incrementAll (Nothing::Maybe Int)|]) (?== Nothing)
ex2_fmap2_examples =
conjoin [$(testing' [|fmap2 negate [[1,2],[3]]|]) (?==[[-1,-2],[-3]])
,$(testing' [|fmap2 head [Just "abcd",Nothing,Just "efgh"]|]) (?==[Just 'a',Nothing,Just 'e'])]
ex2_fmap3_examples =
conjoin [$(testing' [|fmap3 negate [[[1,2],[3]],[[4],[5,6]]]|]) (?==[[[-1,-2],[-3]],[[-4],[-5,-6]]])
,$(testing' [|fmap3 not (Just [Just False, Nothing])|]) (?==Just [Just True,Nothing])]
deriving instance Eq a => Eq (Result a)
ex3_num =
forAll_ $ \(k::Int) ->
counterexample ("fmap (+1) (MkResult "++show k++")") $
fmap (+(1::Int)) (MkResult k) ?== MkResult (k+1)
ex3_empties =
$(testing' [|fmap not NoResult|]) (?== NoResult)
.&.
$(testing' [|fmap not (Failure "oh no.")|]) (?== Failure "oh no.")
.&.
$(testing' [|fmap not (Failure "Mein Gott!")|]) (?== Failure "Mein Gott!")
deriving instance Eq a => Eq (List a)
toList = foldr LNode Empty
ex4_num =
forAll_ $ \(xs::[Int]) ->
let l = toList xs
in counterexample ("fmap (+1) ("++show l++")") $
fmap (+1) l ?== toList (map (+1) xs)
ex4_bool =
forAll_ $ \(bs::[Bool]) ->
let l = toList bs in
counterexample ("fmap not ("++show l++")") $
fmap not l ?== toList (map not bs)
deriving instance Eq a => Eq (TwoList a)
toTwoList :: [a] -> TwoList a
toTwoList [] = TwoEmpty
toTwoList (x:y:xs) = TwoNode x y (toTwoList xs)
ex5_num =
forAll_ $ \(xs::[Int]) ->
even (length xs) ==>
let l = toTwoList xs
in counterexample ("fmap (+1) ("++show l++")") $
fmap (+1) l ?== toTwoList (map (+1) xs)
ex5_bool =
forAll_ $ \(bs::[Bool]) ->
even (length bs) ==>
let l = toTwoList bs in
counterexample ("fmap not ("++show l++")") $
fmap not l ?== toTwoList (map not bs)
ex6_list =
forAll_ $ \(bs::[Bool]) ->
forAll_ $ \b ->
$(testing [|count b bs|]) (?==length (filter (==b) bs))
ex6_maybe =
forAllBlind (choose ('a','z')) $ \c ->
forAllBlind (choose ('a','z') `suchThat` (/=c)) $ \d ->
conjoin [$(testing [|count c n|]) (?==0)
,$(testing [|count c (Just c)|]) (?==1)
,$(testing [|count d (Just c)|]) (?==0)]
where n = Nothing :: Maybe Char
ex7_list =
forAll_ $ \(is::[Int]) ->
forAll_ $ \(js::[Int]) ->
$(testing [|inBoth (nub is) (nub js)|]) (hasElements $ intersect (nub is) (nub js))
ex7_maybe =
forAll_ $ \(i::Int) ->
forAll_ $ \j ->
conjoin [$(testing [|inBoth (Just i) (Just j)|]) (?==if i==j then [i] else [])
,$(testing [|inBoth (Just i) (Just i)|]) (?==[i])
,$(testing [|inBoth (Just i) n|]) (?==[])]
where n = Nothing :: Maybe Int
ex8_bool =
forAll_ $ \(xs::[Bool]) ->
let l = toList xs
in counterexample ("foldr (:) [] ("++show l++")") $
foldr (:) [] l ?== xs
ex8_num =
forAll_ $ \(NonEmpty (is::[Int])) ->
let l = toList is
in $(testing [|minimum l|]) (?==minimum is)
ex9_bool =
forAll_ $ \(xs::[Bool]) ->
even (length xs) ==>
let l = toTwoList xs
in counterexample ("foldr (:) [] ("++show l++")") $
foldr (:) [] l ?== xs
ex9_num =
forAll_ $ \(NonEmpty (is::[Int])) ->
even (length is) ==>
let l = toTwoList is
in $(testing [|minimum l|]) (?==minimum is)
ex10_1 =
forAll_ $ \(i::Int) ->
counterexample ("runFun (fmap not (Fun even)) "++show i) $
runFun (fmap not (Fun even)) i ?== odd i
ex10_2 =
forAll_ $ \(i::Int) ->
counterexample ("runFun (fmap (*2) (Fun (\\i -> i))) "++show i) $
runFun (fmap (*2) (Fun id)) i ?== 2*i
deriving instance Eq a => Eq (Tree a)
ex11_fmap_even = conjoin
[$(testing' [|fmap even Leaf|]) (?==Leaf)
,$(testing' [|fmap even (Node 3 Leaf Leaf)|]) (?==Node False Leaf Leaf)
,$(testing' [|fmap even (Node 2 Leaf Leaf)|]) (?==Node True Leaf Leaf)
,$(testing' [|fmap even (Node 2 (Node 3 Leaf Leaf) Leaf)|]) (?==Node True (Node False Leaf Leaf) Leaf)
,$(testing' [|fmap even (Node 2 (Node 3 Leaf Leaf) (Node 4 Leaf Leaf))|]) (?==Node True (Node False Leaf Leaf) (Node True Leaf Leaf))]
trees :: Int -> Gen (Tree Int, Tree Int)
trees 0 = return (Leaf,Leaf)
trees n = do
i <- choose (0,10)
let j = i+2
nleft <- choose (0,n-1)
nright <- choose (0,n-1)
(iLeft,jLeft) <- trees nleft
(iRight,jRight) <- trees nright
return (Node i iLeft iRight, Node j jLeft jRight)
m_fmap n = forAllBlind (trees n) $ \(from,to) ->
counterexample ("fmap (+2) ("++show from++")") $
fmap (+2) from ?== to
ex11_fmap_plus = conjoin [m_fmap 0
,m_fmap 1
,m_fmap 2
,m_fmap 3
,m_fmap 4]
treeAndSum 0 = return (0,Leaf)
treeAndSum n = do
(lsum,l) <- treeAndSum (n-1)
(rsum,r) <- treeAndSum (n-1)
val <- choose (0,10::Int)
return (val+rsum+lsum, Node (Sum val) l r)
m_treeSum_Sum n = forAllBlind (treeAndSum n) $ \(s,t) ->
$(testing [|sumTree t|]) (?==Sum s)
ex11_sumTree_int = conjoin [m_treeSum_Sum 0
,m_treeSum_Sum 1
,m_treeSum_Sum 2
,m_treeSum_Sum 3]
split :: [a] -> Gen ([a],[a])
split xs = do
i <- choose (0,length xs-1)
return $ (take i xs, drop i xs)
listToTree 0 xs = return (Node xs Leaf Leaf)
listToTree n xs = frequency
[(1,return (Node xs Leaf Leaf))
,(4,do
(left,rest) <- split xs
(me,right) <- split rest
l <- listToTree (n-1) left
r <- listToTree (n-1) right
return $ Node me l r)]
m_sumTree_list n = forAll_ $ \(is::[Int]) ->
forAllBlind (listToTree n is) $ \tree ->
$(testing [|sumTree tree|]) (?==is)
ex11_sumTree_list = conjoin [m_sumTree_list 0
,m_sumTree_list 1
,m_sumTree_list 2
,m_sumTree_list 3]