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

Simplified eliminators #207

Merged
merged 33 commits into from
Sep 29, 2019
Merged

Simplified eliminators #207

merged 33 commits into from
Sep 29, 2019

Conversation

robrix
Copy link
Contributor

@robrix robrix commented Sep 2, 2019

@robrix robrix mentioned this pull request Sep 3, 2019
@robrix robrix changed the base branch from separate-carrier-and-effect-modules to master September 23, 2019 00:32
@robrix robrix changed the base branch from master to to-the-left-to-the-left September 28, 2019 18:27
Copy link
Contributor Author

@robrix robrix left a comment

Choose a reason for hiding this comment

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

Ready for review.

@@ -25,6 +26,9 @@ 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

runChooseS :: (Applicative m, Semigroup b) => (a -> m b) -> ChooseC m a -> m b
runChooseS leaf = runChoose (liftA2 (<>)) leaf
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could supply runChooseA, but:

  1. You’d be giving up the assurance that you’ll have a non-empty container of results.

  2. You can always use runChoose (liftA2 (<|>)) (pure . pure) or runChooseS Alt >=> getAlt if you must.

By contrast, there’s no reason to supply runChooseM as every Monoid is already a Semigroup.

runCull (CullC m) = runNonDetC (runReader False m) (<|>) pure empty
-- prop> run (runCull (liftA2 (<|>)) (pure . pure) (pure empty) (pure a <|> pure b)) === [a, b]
runCull :: (m b -> m b -> m b) -> (a -> m b) -> m b -> CullC m a -> m b
runCull fork leaf nil = runNonDet fork leaf nil . runReader False . runCullC
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is much more flexible than the previous handlers employed (which required the use of another carrier for nondeterminism).

We no longer provide a handler interpreting into an underlying Alternative instance; instead, runCull (<|>) pure empty can be used, if one absolutely must.

@@ -58,7 +66,7 @@ instance Alternative (NonDetC m) where

instance Monad (NonDetC m) where
NonDetC a >>= f = NonDetC $ \ fork leaf nil ->
a fork (\ a' -> runNonDetC (f a') fork leaf nil) nil
a fork (runNonDet fork leaf nil . f) nil
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was by no means the point of this PR, but it’s certainly a nice side benefit that we can use the eliminators point-free.

@@ -5,7 +5,7 @@ module Control.Carrier.Trace.Returning
-- * Trace carrier
, runTrace
, TraceC(..)
-- * Re-exports
Copy link
Contributor Author

Choose a reason for hiding this comment

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

conform!

@@ -36,5 +36,4 @@ cull m = send (Cull m pure)
-- >>> import Test.QuickCheck
-- >>> import Control.Carrier.Cull.Church
-- >>> import Control.Carrier.NonDet.Church
-- >>> import Control.Carrier.Pure
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is re-exported by Control.Carrier, and I missed cleaning these up.

@robrix robrix marked this pull request as ready for review September 28, 2019 19:21
@robrix robrix changed the base branch from to-the-left-to-the-left to master September 29, 2019 16:09
Copy link
Collaborator

@patrickt patrickt left a comment

Choose a reason for hiding this comment

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

Small quibbles that you can choose to fix or not, but other than that this is ready to go.

- The primary handlers (`runChoose`, `runNonDet`, `runCut`, `runCull`) take multiple continuations.
- Handlers which return an `Alternative` are suffixed with `A`, e.g. `runNonDetA`.
- Handlers which return a `Monoid` are suffixed with `M`, e.g. `runNonDetM`.
- Handlers which return a `Semigroup` are suffixed with `S`, e.g. `runChooseS`.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Loving this.

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

runChooseS :: (Applicative m, S.Semigroup b) => (a -> m b) -> ChooseC m a -> m b
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we get documentation for this, mentioning that it uses <> to merge its results?

mfix (runChoose (liftA2 Fork) (pure . Leaf)
mfix (runChoose
(liftA2 Fork)
(pure . Leaf)
. f . fromJust . fold (Alt.<|>) Just)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we use something more descriptive than fromJust here? fromMaybe (“error: ChooseC mfix returned Just”)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is being replaced in #233 anyway, so I’mma leave it as-is.

@robrix robrix merged commit 300e46e into master Sep 29, 2019
@robrix robrix deleted the simplified-eliminators branch September 29, 2019 19:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

NonDetC can’t produce a Set in a single step
2 participants