{-# LANGUAGE ScopedTypeVariables #-} module Test.Monad.Cont where import Control.Monad.Cont import Data.Void (absurd) import Test.QuickCheck.HigherOrder (Equation(..)) -- * 'MonadCont' laws -- Reference: https://mail.haskell.org/pipermail/libraries/2019-October/030041.html callCC_const :: forall m a. MonadCont m => m a -> Equation (m a) callCC_const m = callCC (const m) :=: m callCC_id :: forall m a. MonadCont m => a -> Equation (m a) callCC_id a = callCC ($ a) :=: pure a callCC_bind :: forall m a. MonadCont m => m a -> Equation (m a) callCC_bind m = callCC ((>>=) m) :=: m callCC_phantom :: forall m a b. MonadCont m => ((a -> m b) -> m a) -> Equation (m a) callCC_phantom f = callCC f :=: callCC (f . (fmap . fmap) absurd) callCC_left_zero :: forall m a b. MonadCont m => ((a -> m b) -> m a) -> ((a -> m b) -> b -> m a) -> Equation (m a) callCC_left_zero f g = callCC (\k -> f k >>= (\a -> k a >>= g k)) :=: callCC f