packages feed

ether-0.5.0.0: test/Regression/T11.hs

module Regression.T11 (test11) where

import Ether

import Data.Bool
import qualified Control.Monad.State as T
import qualified Control.Monad.Reader as T

import Test.Tasty
import Test.Tasty.QuickCheck

data STag

testEther
  :: ( MonadState STag [Integer] m
     , T.MonadState Bool m
     , T.MonadReader Integer m )
  => m ()
testEther = do
  T.modify not
  f <- bool negate id <$> T.get
  n <- T.ask
  T.local succ testEther
  modify @STag (f n:)

model :: Integer -> [Integer]
model n = zipWith ($) (cycle [id, negate]) [n..]

runner1 n
  = flip (T.runReader) n
  . flip (execLazyStateT @STag) []
  . flip T.evalStateT False

runner2 n
  = flip T.evalState False
  . flip (execLazyStateT @STag) []
  . flip T.runReaderT n

test11 :: TestTree
test11 = testGroup "T11: Lazy sequence"
  [ testProperty "runner₁ works"
    $ \l n -> property
    $ take l (runner1 n testEther) == take l (model n)
  , testProperty "runner₂ works"
    $ \l n -> property
    $ take l (runner2 n testEther) == take l (model n)
  , testProperty "runner₁ == runner₂"
    $ \l n -> property
    $ take l (runner1 n testEther) == take l (runner2 n testEther)
  ]