-
Notifications
You must be signed in to change notification settings - Fork 53
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
Base instances #206
Base instances #206
Changes from 11 commits
c9a1100
77009c8
1c48615
2094861
d3398a1
a6005d1
3683078
7b01e03
cc2478b
2721e67
c0d047e
7cfd492
f8f70f0
639bf3f
ad5ce6a
02de975
92f297b
40bc5df
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*.hs-boot linguist-language=Haskell |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{-# LANGUAGE ConstraintKinds #-} | ||
module Control.Carrier | ||
( -- * Re-exports | ||
module Control.Carrier.Class | ||
, module Control.Carrier.Pure | ||
, module Control.Effect.Class | ||
, (:+:)(..) | ||
, Has | ||
, send | ||
) where | ||
|
||
import {-# SOURCE #-} Control.Carrier.Class | ||
import Control.Carrier.Pure | ||
import Control.Effect.Class | ||
import Control.Effect.Sum | ||
|
||
type Has eff sig m = (Inject eff sig, Carrier sig m) | ||
|
||
send :: Has eff sig m => eff m a -> m a |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,40 @@ | ||
{-# LANGUAGE FunctionalDependencies #-} | ||
{-# LANGUAGE FlexibleInstances, FunctionalDependencies #-} | ||
module Control.Carrier.Class | ||
( Carrier(..) | ||
) where | ||
|
||
import Control.Effect.Class | ||
import Control.Effect.Choose (Choose(..)) | ||
import Control.Effect.Empty (Empty(..)) | ||
import Control.Effect.Error (Error(..)) | ||
import Control.Effect.NonDet (NonDet) | ||
import Control.Effect.Reader (Reader(..)) | ||
import Control.Effect.Sum ((:+:)(..)) | ||
import Control.Effect.Writer (Writer(..)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The payoff: we can import all of these effect modules right where we define the |
||
import Control.Monad ((<=<)) | ||
|
||
-- | 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 | ||
|
||
|
||
instance Carrier Empty Maybe where | ||
eff Empty = Nothing | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And that in turn allows us to implement |
||
|
||
instance Carrier (Error e) (Either e) where | ||
eff (Throw e) = Left e | ||
eff (Catch m h k) = either (k <=< h) k m | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I called this branch There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Checking my understanding: I could have an effect stack There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, exactly. |
||
|
||
instance Carrier (Reader r) ((->) r) where | ||
eff (Ask k) r = k r r | ||
eff (Local f m k) r = k (m (f r)) r | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This allows you to use these instances anywhere expecting the type in question: id' :: a -> a
id' = ask Well, almost anywhere. I can’t figure out how to make this instance available to e.g. |
||
|
||
instance Carrier NonDet [] where | ||
eff (L Empty) = [] | ||
eff (R (Choose k)) = k True ++ k False | ||
|
||
instance Monoid w => Carrier (Writer w) ((,) w) where | ||
eff (Tell w (w', k)) = (mappend w w', k) | ||
eff (Listen m k) = uncurry k m | ||
eff (Censor f (w, a) k) = let (w', a') = k a in (mappend (f w) w', a') |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{-# LANGUAGE FunctionalDependencies #-} | ||
module Control.Carrier.Class | ||
( Carrier(..) | ||
) where | ||
|
||
import Control.Effect.Class | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In an effort to fix the aforementioned problem where |
||
|
||
class (HFunctor sig, Monad m) => Carrier sig m | m -> sig where | ||
eff :: sig m a -> m a |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,7 +11,7 @@ module Control.Effect.Choose | |
, Choosing(..) | ||
) where | ||
|
||
import Control.Carrier | ||
import {-# SOURCE #-} Control.Carrier | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These directives indicate that it’s |
||
import Control.Effect.Empty | ||
import Data.Bool (bool) | ||
import Data.List.NonEmpty (NonEmpty (..)) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need
.hs-boot
files forControl.Carrier
andControl.Carrier.Class
to break the cycles in the module graph.