{-# LANGUAGE FlexibleContexts, NoMonomorphismRestriction #-} {-# LANGUAGE TypeOperators, DataKinds #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TemplateHaskell #-} {-# OPTIONS_GHC -fno-warn-unused-do-bind #-} module Control.Eff.State.OnDemand.Test (testGroups) where import Test.HUnit hiding (State) import Control.Eff import Control.Eff.Exception import Control.Eff.State.OnDemand import Test.Framework.TH import Test.Framework.Providers.HUnit testGroups = [ $(testGroupGenerator) ] case_LazierState_ex1 :: Assertion case_LazierState_ex1 = let actual = run $ runState lex1 0 in assertEqual "OnDemandState: ex1" ((), 1::Int) actual where lex1 = do onDemand lex1 put (1::Int) case_LazierState_ex3 :: Assertion case_LazierState_ex3 = let (x,s) = run $ runState lex3 (undefined::[Int]) in assertEqual "OnDemandState: ex3" ((),[1,1,1,1,1]) (x,take 5 s) where lex3 = do onDemand lex3 modify ((1::Int):) -- a bit more interesting case_LazierState_ex4 = let (x,s) = run $ runState lex4 [] in assertEqual "OnDemandState: ex4" expect (take 7 $ x,take 5 $ s) where expect = ([3,2,3,2,3,2,3],[3,2,3,2,3]) lex4 :: Eff '[OnDemandState [Int]] [Int] lex4 = do modify ((0::Int):) onDemand lex4 modify ((1::Int):) onDemand (onDemand lex4 :: Eff '[OnDemandState [Int]] [Int]) modify ((2::Int):) modify ((3::Int):) get -- Edward's example plus exceptions case_LazierState_ex5 :: Assertion case_LazierState_ex5 = let -- the annotations below are needed for assertEqual ex5Run :: Either [Int] () = fst . run $ runState (runError lex5) (undefined::[Int]) ex51Run :: Either [Int] ((), [Int]) = run $ runError $ runState lex5 (undefined::[Int]) in assertEqual "OnDemandState ex5" (Left ones) ex5Run >> assertEqual "OnDemandState ex51" (Left ones) ex51Run where ones = take 5 $ repeat (1::Int) lex31 :: Member (OnDemandState [Int]) r => Eff r () lex31 = do onDemand (lex31 :: Eff '[OnDemandState [Int]] ()) modify ((1::Int):) lex5 = do lex31 x <- get throwError ((take 5 x)::[Int]) case_LazierState_st :: Assertion case_LazierState_st = let stF :: ((Int,Int,Int),Int) = run $ runState st (0::Int) stB0 :: ((Int,Int,Int),Int) = runStateBack0 st stB :: ((Int,Int,Int),Int) = runStateBack st in assertEqual "OnDemandState stF" ((0,1,3),4) stF >> assertEqual "OnDemandState stB0" ((1,2,4),1) stB0 >> assertEqual "OnDemandState stB" ((1,2,4),1) stB where st = do x <- get put (1::Int) put (1::Int) y <- get put (2::Int) put (10::Int) put (3::Int) z <- get put (4::Int) return (x,y,z) case_LazierState_ones :: Assertion case_LazierState_ones = let ones :: [Int] = snd $ runStateBack $ do s <- get put ((1::Int):s) in assertEqual "OnDemandState ones" [1,1,1,1,1] (take 5 ones)