Skip to content

Commit

Permalink
Define an Alternative module giving implementations in terms of Alter…
Browse files Browse the repository at this point in the history
…native.
  • Loading branch information
robrix committed Sep 21, 2019
1 parent c73d97c commit a60ee75
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
1 change: 1 addition & 0 deletions fused-effects.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ library
, Control.Carrier.Trace.Returning
, Control.Carrier.Writer.Strict
, Control.Effect
, Control.Effect.Alternative
, Control.Effect.Choose
, Control.Effect.Class
, Control.Effect.Cull
Expand Down
43 changes: 43 additions & 0 deletions src/Control/Effect/Alternative.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
module Control.Effect.Alternative
( -- * NonDet effects
module Control.Effect.Choose
, module Control.Effect.Empty
, oneOf
, foldMapA
-- * Re-exports
, Alternative(..)
, guard
) where

import Control.Applicative (Alternative(..))
import Control.Effect.Choose hiding ((<|>), many, some)
import Control.Effect.Empty hiding (empty, guard)
import Control.Monad (guard)
import Data.Coerce
import Data.Monoid (Alt(..))

-- | Nondeterministically choose an element from a 'Foldable' collection.
-- This can be used to emulate the style of nondeterminism associated with
-- programming in the list monad:
-- @
-- pythagoreanTriples = do
-- a <- oneOf [1..10]
-- b <- oneOf [1..10]
-- c <- oneOf [1..10]
-- guard (a^2 + b^2 == c^2)
-- pure (a, b, c)
-- @
oneOf :: (Foldable t, Alternative m) => t a -> m a
oneOf = foldMapA pure

-- | Map a 'Foldable' collection of values into a nondeterministic computation using the supplied action.
foldMapA :: (Foldable t, Alternative m) => (a -> m b) -> t a -> m b
foldMapA f = getAlt #. foldMap (Alt #. f)


-- | Compose a function operationally equivalent to 'id' on the left.
--
-- cf https://github.com/fused-effects/diffused-effects/pull/1#discussion_r323560758
(#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c)
(#.) _ = coerce
{-# INLINE (#.) #-}

0 comments on commit a60ee75

Please sign in to comment.