{-# LANGUAGE FlexibleContexts #-}
import Control.Eff
import Control.Eff.Lift
import Control.Eff.State
import Control.Monad (void)
import Data.Typeable
import Test.Framework (defaultMain, testGroup)
import Test.Framework.Providers.QuickCheck2
import Test.QuickCheck
main :: IO ()
main = defaultMain tests
allEqual :: Eq a => [a] -> Bool
allEqual = all (uncurry (==)) . pairs
where
pairs l = zip l $ tail l
safeLast [] = Nothing
safeLast l = Just $ last l
testDocs :: [Integer] -> Property
testDocs l = let
(total1, ()) = run $ runState 0 $ sumAll l
(last1, ()) = run $ runWriter $ writeAll l
(total2, (last2, ())) = run $ runState 0 $ runWriter $ writeAndAdd l
(last3, (total3, ())) = run $ runWriter $ runState 0 $ writeAndAdd l
in allEqual [safeLast l, last1, last2, last3]
.&&. allEqual [sum l, total1, total2, total3]
where
writeAll :: (Typeable a, Member (Writer a) e)
=> [a]
-> Eff e ()
writeAll = mapM_ putWriter
sumAll :: (Typeable a, Num a, Member (State a) e)
=> [a]
-> Eff e ()
sumAll = mapM_ (onState . (+))
writeAndAdd :: (Member (Writer Integer) e, Member (State Integer) e)
=> [Integer]
-> Eff e ()
writeAndAdd l = do
writeAll l
sumAll l
tests = [
testProperty "Documentation example." testDocs
]