Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate carrier and effect modules #204

Merged
merged 113 commits into from
Sep 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
113 commits
Select commit Hold shift + click to select a range
9f9cce4
Merge branch '🔥-random' into separate-carrier-and-effect-modules
robrix Aug 25, 2019
35b7563
Rename Control.Effect.Carrier to Control.Carrier.
robrix Aug 25, 2019
bd536bb
Move the lazy & strict state carriers under Control.Carrier.State.
robrix Aug 25, 2019
4234fa7
Rename Control.Effect.State.Internal to Control.Effect.State.
robrix Aug 25, 2019
7aa358b
Combine some re-exports.
robrix Aug 25, 2019
03af9be
Move Control.Effect.Interpret to Control.Carrier.Interpret.
robrix Aug 25, 2019
7b8396d
Re-export HFunctor from Control.Effect.
robrix Aug 25, 2019
78182bf
Move Control.Carrier to Control.Carrier.Class.
robrix Aug 25, 2019
88a513a
Reintroduce Control.Carrier for convenient imports.
robrix Aug 25, 2019
18d38fb
Rename Control.Effect.Interpose to Control.Carrier.Interpose.
robrix Aug 25, 2019
75acb21
Stub in a module for the ignoring Trace carrier.
robrix Aug 25, 2019
e43af18
Move TraceByIgnoringC &c. into Control.Carrier.Trace.Ignoring.
robrix Aug 25, 2019
47681cd
Rename runTraceByIgnoring to runTrace.
robrix Aug 25, 2019
479500e
Rename TraceByIgnoringC to TraceC.
robrix Aug 25, 2019
7b27ec2
Move TraceByPrintingC into a new module.
robrix Aug 25, 2019
133883d
Rename TraceByPrintingC to TraceC.
robrix Aug 25, 2019
ab00ad8
Rename runTraceByPrinting to runTrace.
robrix Aug 25, 2019
e2b81ea
Move TraceByReturningC into its own module.
robrix Aug 25, 2019
8b47c87
Rename TraceByReturningC to TraceC.
robrix Aug 25, 2019
915a66a
Rename runTraceByReturning to runTrace.
robrix Aug 25, 2019
43b89e1
Add the doctests setup boilerplate.
robrix Aug 25, 2019
ad8e644
Simplify the language extensions for Control.Effect.Trace.
robrix Aug 25, 2019
dcc358e
There are no tests in this file.
robrix Aug 25, 2019
9e24d62
Move ReaderC into its own module.
robrix Aug 25, 2019
49555e7
Move ErrorC into its own module.
robrix Aug 25, 2019
2775984
Add a missing import for the doctests.
robrix Aug 25, 2019
ff471aa
Move WriterC into its own module.
robrix Aug 31, 2019
443fac2
Don’t rename the module.
robrix Aug 31, 2019
2adc771
Tidy up the language extensions.
robrix Aug 31, 2019
b7f3d89
Move ResumableC into its own module.
robrix Aug 31, 2019
027c7f8
Move SomeError into Control.Carrier.Resumable.Either.
robrix Aug 31, 2019
ef2277c
Move Control.Carrier.Error to Control.Carrier.Error.Either.
robrix Aug 31, 2019
4b858e0
Move ChooseC into its own module.
robrix Sep 1, 2019
4ce3c63
Rename Control.Effect.NonDet to Control.Carrier.NonDet.Church.
robrix Sep 1, 2019
0975f43
Re-export Carrier/Member/run from the carrier modules only.
robrix Sep 1, 2019
1d03a98
:fire: OnceC.
robrix Sep 1, 2019
56b8e3b
Move CullC into its own module.
robrix Sep 1, 2019
24f59e4
Move CutC into its own module.
robrix Sep 1, 2019
2c588fd
Move EmptyC into its own module.
robrix Sep 1, 2019
5976f52
Correct a doctest.
robrix Sep 1, 2019
2fc6329
Move FailC into its own module.
robrix Sep 1, 2019
bc3d9fc
Move FreshC into its own module.
robrix Sep 1, 2019
6481c42
Rename the Resumable carrier module.
robrix Sep 1, 2019
9cb5b52
Move ResumableWithC into its own module & rename it.
robrix Sep 1, 2019
a5ec56a
Move ResourceC into its own module.
robrix Sep 1, 2019
ed5c43f
Merge branch '🔥-random' into separate-carrier-and-effect-modules
robrix Sep 1, 2019
2764c1a
Move LiftC into its own module.
robrix Sep 1, 2019
c4bbc55
Move PureC into its own module.
robrix Sep 1, 2019
7d383af
Merge branch '🔥-deprecations' into separate-carrier-and-effect-modules
robrix Sep 1, 2019
5d47ab0
Spacing.
robrix Sep 1, 2019
22ebc73
Move HFunctor & Effect into their own module.
robrix Sep 1, 2019
f7938e9
Move handleCoercible into Control.Effect.Class.
robrix Sep 1, 2019
e32881b
Merge branch 'the-great-divide' into separate-carrier-and-effect-modules
robrix Sep 3, 2019
9f5bda2
Add the abort smart constructor back in.
robrix Sep 3, 2019
6fc8d2a
Whoops.
robrix Sep 3, 2019
50c0d4a
:fire: a redundant import.
robrix Sep 4, 2019
034313a
Merge branch 'the-great-divide' into separate-carrier-and-effect-modules
robrix Sep 17, 2019
9f0c274
Add a note about removing OnceC.
robrix Sep 17, 2019
12fc819
Note that the carriers have all moved.
robrix Sep 17, 2019
51c4139
Qualify the re-export of MonadFail.
robrix Sep 17, 2019
f54d246
Merge branch 'master' into separate-carrier-and-effect-modules
robrix Sep 19, 2019
2172610
Merge branch 'master' into separate-carrier-and-effect-modules
robrix Sep 21, 2019
35beaf4
Correct the imports in the benchmarks.
robrix Sep 21, 2019
32fb382
Correct the imports in the examples.
robrix Sep 21, 2019
376be33
Correct the imports in the tests.
robrix Sep 21, 2019
d46d29f
Get the doctests passing again.
robrix Sep 21, 2019
e4bf415
Rename the cull carrier module to .Church.
robrix Sep 21, 2019
33102e5
Rename the Empty carrier module to .Direct.
robrix Sep 21, 2019
651cb10
Revert "Rename the Empty carrier module to .Direct."
robrix Sep 21, 2019
75e0b13
Rename the Fail carrier module to .Either.
robrix Sep 21, 2019
7e41347
Re-export MonadFail from the Fail effect module.
robrix Sep 21, 2019
2a91353
Handle Fail in the Carrier instance.
robrix Sep 21, 2019
61e047a
:fire: a redundant import.
robrix Sep 21, 2019
e3cd41e
Re-export a bunch of stuff from Control.Carrier.
robrix Sep 21, 2019
27dd510
Import Control.Carrier in general.
robrix Sep 21, 2019
6e175f1
Don’t re-export anything from Control.Carrier.Class.
robrix Sep 21, 2019
1cd444b
Move the Carrier instance for PureC into Control.Carrier.Pure.
robrix Sep 21, 2019
4d3d85d
Tidy up the language extensions in Control.Carrier.Class.
robrix Sep 21, 2019
c68e311
Move send into Control.Effect.Sum.
robrix Sep 21, 2019
822620f
Rename Control.Carrier.Resumable.Abort to .Either.
robrix Sep 21, 2019
d8e37b1
:fire: a redundant file.
robrix Sep 21, 2019
41bc7c3
Reintroduce Control.Effect.NonDet, re-exporting Choose, Empty, & Alte…
robrix Sep 21, 2019
d10d041
Rename abort to empty.
robrix Sep 21, 2019
dc07eb4
Rename choose to <|>.
robrix Sep 21, 2019
aef5e94
Combine the headings for the nondet effects.
robrix Sep 21, 2019
1f3f887
Move oneOf into Control.Effect.NonDet.
robrix Sep 21, 2019
ef2850a
Use the #. trick to optimize oneOf.
robrix Sep 21, 2019
2b760ba
:memo: #.
robrix Sep 21, 2019
64640e2
Introduce foldMapA to map a Foldable container into an Alternative co…
robrix Sep 21, 2019
7184084
Define oneOf using foldMapA.
robrix Sep 21, 2019
059d92f
:memo: foldMapA.
robrix Sep 21, 2019
e42e999
Define a guard operation for Empty effects.
robrix Sep 21, 2019
193b58a
Add a note about foldMapA to the changelog.
robrix Sep 21, 2019
36adb35
:memo: guard.
robrix Sep 21, 2019
c73d97c
Re-export the Alternative-based definition of guard.
robrix Sep 21, 2019
a60ee75
Define an Alternative module giving implementations in terms of Alter…
robrix Sep 21, 2019
1ce0655
:memo: Control.Effect.Alternative.
robrix Sep 21, 2019
53aa8a9
:memo: Control.Effect.NonDet.
robrix Sep 21, 2019
700fe3c
Define a Choosing newtype.
robrix Sep 21, 2019
de31527
Define a Semigroup instance for Choosing.
robrix Sep 21, 2019
3ff5d28
Define a Monoid instance for Choosing.
robrix Sep 21, 2019
595cbcb
Define the Control.Effect.NonDet interfaces in terms of the effects.
robrix Sep 21, 2019
358c54d
Define oneOf & foldMapA via the Alternative interfaces.
robrix Sep 21, 2019
f65b114
Revert "Define oneOf & foldMapA via the Alternative interfaces."
robrix Sep 21, 2019
6b4a0be
Note the addition of Control.Effect.Alternative in the changelog.
robrix Sep 21, 2019
744d6f9
Revert "Note the addition of Control.Effect.Alternative in the change…
robrix Sep 21, 2019
0c70e38
Revert "Define the Control.Effect.NonDet interfaces in terms of the e…
robrix Sep 21, 2019
f49bc6d
Revert ":memo: Control.Effect.NonDet."
robrix Sep 21, 2019
c25bf81
Revert ":memo: Control.Effect.Alternative."
robrix Sep 21, 2019
db163b3
Revert "Define an Alternative module giving implementations in terms …
robrix Sep 21, 2019
3e2ebb9
:fire: a redundant import.
robrix Sep 21, 2019
de4e147
Use a qualified import of Semigroup to accommodate 8.2.
robrix Sep 21, 2019
031e95d
Explicitly give the canonical definition of mappend.
robrix Sep 21, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

- Adds a `oneOf` function to `Control.Effect.NonDet` to provide an idiom for the common case of nondeterministically selecting from a container. ([#201](https://github.com/fused-effects/fused-effects/pull/201))

- Adds a `foldMapA` function to `Control.Effect.NonDet` mapping containers into nondeterministic computations using a supplied function. ([#204](https://github.com/fused-effects/fused-effects/pull/204))

## Backwards-incompatible changes

- Improves the performance of `runInterpret` using reflection, changing its signature slightly ([#193](https://github.com/fused-effects/fused-effects/pull/193), h/t [@ocharles](https://github.com/ocharles)).
Expand All @@ -16,6 +18,10 @@

- Removes the `NonDet` effect, replacing it with the combination of the new `Choose` and `Empty` effects ([#199](https://github.com/fused-effects/fused-effects/pull/199)).

- Removes the `OnceC` carrier for `Cull` effects, replacing it with the composition of `CullC` on some other `Alternative` carrier, e.g. `NonDetC` ([#204](https://github.com/fused-effects/fused-effects/pull/204)).

- Moves all the carriers into their own modules in the `Control.Carrier` namespace. Several have also been renamed, e.g. the various `Trace` carriers are all named `TraceC` within their separate modules, and should be imported qualified if disambiguation is required. This simplifies naming schemes, and ensures that the choice of e.g. strict or lazy carrier is always made consciously and expliclty, instead of defaulting to whichever is exported by the effect module ([#204](https://github.com/fused-effects/fused-effects/pull/204)).

# v0.5.0.1

- Adds support for ghc 8.8.1.
Expand Down
8 changes: 4 additions & 4 deletions benchmark/Bench.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ module Main
( main
) where

import Control.Effect.Carrier
import Control.Effect.Interpret
import Control.Effect.Writer
import Control.Effect.State
import Control.Carrier
import Control.Carrier.Interpret
import Control.Carrier.State.Strict
import Control.Carrier.Writer.Strict
import Control.Monad (ap, replicateM_)
import Data.Functor.Identity
import Data.Monoid (Sum(..))
Expand Down
4 changes: 1 addition & 3 deletions benchmark/NonDet/NQueens.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@
module NonDet.NQueens (runQueens, benchmark) where

import Control.Applicative
import Control.Effect
import Control.Effect.NonDet
import Control.Monad
import Control.Carrier.NonDet.Church
import Data.Foldable
import Data.List
import Gauge hiding (benchmark)
Expand Down
8 changes: 4 additions & 4 deletions examples/Parser.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ module Parser
( spec
) where

import Control.Effect.Carrier
import Control.Effect.Cut
import Control.Effect.NonDet
import Control.Effect.State
import Control.Carrier
import Control.Carrier.Cut.Church
import Control.Carrier.NonDet.Church
import Control.Carrier.State.Strict
import Control.Monad (replicateM)
import Data.Char
import Data.List (intercalate)
Expand Down
8 changes: 4 additions & 4 deletions examples/ReinterpretLog.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ module ReinterpretLog
, runApplication
) where

import Control.Effect.Carrier
import Control.Effect.Lift
import Control.Effect.Reader
import Control.Effect.Writer
import Control.Carrier
import Control.Carrier.Lift
import Control.Carrier.Reader
import Control.Carrier.Writer.Strict
import Control.Monad.IO.Class (MonadIO(..))
import Data.Function ((&))
import Data.Kind (Type)
Expand Down
6 changes: 3 additions & 3 deletions examples/Teletype.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ module Teletype

import Prelude hiding (read)

import Control.Effect.Carrier
import Control.Effect.State
import Control.Effect.Writer
import Control.Carrier
import Control.Carrier.State.Strict
import Control.Carrier.Writer.Strict
import Control.Monad.IO.Class
import GHC.Generics (Generic1)
import Test.Hspec
Expand Down
33 changes: 26 additions & 7 deletions fused-effects.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -31,27 +31,46 @@ common common

library
import: common
exposed-modules: Control.Effect
, Control.Effect.Carrier
exposed-modules: Control.Carrier
, Control.Carrier.Choose.Church
, Control.Carrier.Class
, Control.Carrier.Cull.Church
, Control.Carrier.Cut.Church
, Control.Carrier.Empty.Maybe
, Control.Carrier.Error.Either
, Control.Carrier.Fail.Either
, Control.Carrier.Fresh.Strict
, Control.Carrier.Interpose
, Control.Carrier.Interpret
, Control.Carrier.Lift
, Control.Carrier.NonDet.Church
, Control.Carrier.Pure
, Control.Carrier.Reader
, Control.Carrier.Resource
, Control.Carrier.Resumable.Either
, Control.Carrier.Resumable.Resume
, Control.Carrier.State.Lazy
, Control.Carrier.State.Strict
, Control.Carrier.Trace.Ignoring
, Control.Carrier.Trace.Printing
, Control.Carrier.Trace.Returning
, Control.Carrier.Writer.Strict
, Control.Effect
, Control.Effect.Choose
, Control.Effect.Class
, Control.Effect.Cull
, Control.Effect.Cut
, Control.Effect.Empty
, Control.Effect.Error
, Control.Effect.Fail
, Control.Effect.Fresh
, Control.Effect.Interpose
, Control.Effect.Interpret
, Control.Effect.Lift
, Control.Effect.NonDet
, Control.Effect.Pure
, Control.Effect.Reader
, Control.Effect.Resource
, Control.Effect.Resumable
, Control.Effect.State
, Control.Effect.State.Internal
, Control.Effect.State.Lazy
, Control.Effect.State.Strict
, Control.Effect.Sum
, Control.Effect.Trace
, Control.Effect.Writer
Expand Down
12 changes: 12 additions & 0 deletions src/Control/Carrier.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module Control.Carrier
( -- * Re-exports
module Control.Carrier.Class
, module Control.Effect.Class
, module Control.Effect.Sum
, run
) where

import Control.Carrier.Class
import Control.Carrier.Pure
import Control.Effect.Class
import Control.Effect.Sum
90 changes: 90 additions & 0 deletions src/Control/Carrier/Choose/Church.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
{-# LANGUAGE DeriveTraversable, FlexibleInstances, MultiParamTypeClasses, RankNTypes, TypeOperators, UndecidableInstances #-}
module Control.Carrier.Choose.Church
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Carrier modules are now named descriptively of the implementation; .Church here indicates that this is a church-encoded carrier for Choose.

( -- * Choose effect
module Control.Effect.Choose
-- * Choose carrier
, runChoose
, ChooseC(..)
-- * Re-exports
, Carrier
, Member
, run
) where

import Control.Applicative as Alt ((<|>), liftA2)
import Control.Carrier
import Control.Effect.Choose
import Control.Monad (join)
import qualified Control.Monad.Fail as Fail
import Control.Monad.Fix
import Control.Monad.IO.Class
import Control.Monad.Trans.Class
import Data.Maybe (fromJust)
import Prelude hiding (fail)

runChoose :: (m b -> m b -> m b) -> (a -> m b) -> ChooseC m a -> m b
runChoose fork leaf m = runChooseC m fork leaf

-- | A carrier for 'Choose' effects based on Ralf Hinze’s design described in [Deriving Backtracking Monad Transformers](https://www.cs.ox.ac.uk/ralf.hinze/publications/#P12).
newtype ChooseC m a = ChooseC
{ -- | A higher-order function receiving two continuations, respectively implementing choice and 'pure'.
runChooseC :: forall b . (m b -> m b -> m b) -> (a -> m b) -> m b
}
deriving (Functor)

instance Applicative (ChooseC m) where
pure a = ChooseC (\ _ leaf -> leaf a)
{-# INLINE pure #-}
ChooseC f <*> ChooseC a = ChooseC $ \ fork leaf ->
f fork (\ f' -> a fork (leaf . f'))
{-# INLINE (<*>) #-}

instance Monad (ChooseC m) where
ChooseC a >>= f = ChooseC $ \ fork leaf ->
a fork (runChoose fork leaf . f)
{-# INLINE (>>=) #-}

instance Fail.MonadFail m => Fail.MonadFail (ChooseC m) where
fail s = lift (Fail.fail s)
{-# INLINE fail #-}

instance MonadFix m => MonadFix (ChooseC m) where
mfix f = ChooseC $ \ fork leaf ->
mfix (runChoose (liftA2 Fork) (pure . Leaf)
. f . fromJust . fold (Alt.<|>) Just)
>>= fold fork leaf
{-# INLINE mfix #-}

instance MonadIO m => MonadIO (ChooseC m) where
liftIO io = lift (liftIO io)
{-# INLINE liftIO #-}

instance MonadTrans ChooseC where
lift m = ChooseC (\ _ leaf -> m >>= leaf)
{-# INLINE lift #-}

instance (Carrier sig m, Effect sig) => Carrier (Choose :+: sig) (ChooseC m) where
eff (L (Choose k)) = ChooseC $ \ fork leaf -> fork (runChooseC (k True) fork leaf) (runChooseC (k False) fork leaf)
eff (R other) = ChooseC $ \ fork leaf -> eff (handle (Leaf ()) (fmap join . traverse (runChoose (liftA2 Fork) (pure . Leaf))) other) >>= fold fork leaf
{-# INLINE eff #-}


data BinaryTree a = Leaf a | Fork (BinaryTree a) (BinaryTree a)
deriving (Eq, Foldable, Functor, Ord, Show, Traversable)

instance Applicative BinaryTree where
pure = Leaf
{-# INLINE pure #-}
f <*> a = fold Fork (<$> a) f
{-# INLINE (<*>) #-}

instance Monad BinaryTree where
a >>= f = fold Fork f a
{-# INLINE (>>=) #-}


fold :: (b -> b -> b) -> (a -> b) -> BinaryTree a -> b
fold fork leaf = go where
go (Leaf a) = leaf a
go (Fork a b) = fork (go a) (go b)
{-# INLINE fold #-}
11 changes: 11 additions & 0 deletions src/Control/Carrier/Class.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{-# LANGUAGE FunctionalDependencies #-}
module Control.Carrier.Class
( Carrier(..)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of exporting run, Member, &c. from this module, we export them from Control.Carrier. Likewise, send has been moved into Control.Effect.Sum.

) where

import Control.Effect.Class

-- | The class of carriers (results) for algebras (effect handlers) over signatures (effects), whose actions are given by the 'eff' method.
class (HFunctor sig, Monad m) => Carrier sig m | m -> sig where
-- | Construct a value in the carrier for an effect signature (typically a sum of a handled effect and any remaining effects).
eff :: sig m a -> m a
65 changes: 65 additions & 0 deletions src/Control/Carrier/Cull/Church.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{-# LANGUAGE FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, TypeOperators, UndecidableInstances #-}
module Control.Carrier.Cull.Church
( -- * Cull effect
module Control.Effect.Cull
-- * NonDet effects
, module Control.Effect.NonDet
-- * Cull carrier
, runCull
, CullC(..)
-- * Re-exports
, Carrier
, Member
, run
) where

import Control.Carrier
import Control.Carrier.NonDet.Church
import Control.Carrier.Reader
import Control.Effect.Cull
import Control.Effect.NonDet
import Control.Monad (MonadPlus(..))
import qualified Control.Monad.Fail as Fail
import Control.Monad.Fix
import Control.Monad.IO.Class
import Control.Monad.Trans.Class

-- | Run a 'Cull' effect. Branches outside of any 'cull' block will not be pruned.
--
-- prop> run (runNonDet (runCull (pure a <|> pure b))) === [a, b]
runCull :: Alternative m => CullC m a -> m a
runCull (CullC m) = runNonDetC (runReader False m) (<|>) pure empty

newtype CullC m a = CullC { runCullC :: ReaderC Bool (NonDetC m) a }
deriving (Applicative, Functor, Monad, Fail.MonadFail, MonadFix, MonadIO)

instance Alternative (CullC m) where
empty = CullC empty
{-# INLINE empty #-}
l <|> r = CullC $ ReaderC $ \ cull ->
if cull then
NonDetC $ \ fork leaf nil ->
runNonDetC (runReader cull (runCullC l)) fork leaf (runNonDetC (runReader cull (runCullC r)) fork leaf nil)
else
runReader cull (runCullC l) <|> runReader cull (runCullC r)
{-# INLINE (<|>) #-}

instance MonadPlus (CullC m)

instance MonadTrans CullC where
lift = CullC . lift . lift
{-# INLINE lift #-}

instance (Carrier sig m, Effect sig) => Carrier (Cull :+: Empty :+: Choose :+: sig) (CullC m) where
eff (L (Cull m k)) = CullC (local (const True) (runCullC m)) >>= k
eff (R (L Empty)) = empty
eff (R (R (L (Choose k)))) = k True <|> k False
eff (R (R (R other))) = CullC (eff (R (R (R (handleCoercible other)))))
{-# INLINE eff #-}


-- $setup
-- >>> :seti -XFlexibleContexts
-- >>> import Test.QuickCheck
-- >>> import Control.Carrier.NonDet.Church
-- >>> import Control.Carrier.Pure
Loading