Skip to content

Deprecate MonadZero #64

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

Merged
merged 2 commits into from
Nov 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
23 changes: 23 additions & 0 deletions src/Control/Alternative.purs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module Control.Alternative
( class Alternative
, guard
, module Control.Alt
, module Control.Applicative
, module Control.Apply
Expand All @@ -12,6 +13,7 @@ import Control.Applicative (class Applicative, pure, liftA1, unless, when)
import Control.Apply (class Apply, apply, (*>), (<*), (<*>))
import Control.Plus (class Plus, empty)

import Data.Unit (Unit, unit)
import Data.Functor (class Functor, map, void, ($>), (<#>), (<$), (<$>))

-- | The `Alternative` type class has no members of its own; it just specifies
Expand All @@ -25,3 +27,24 @@ import Data.Functor (class Functor, map, void, ($>), (<#>), (<$), (<$>))
class (Applicative f, Plus f) <= Alternative f

instance alternativeArray :: Alternative Array

-- | Fail using `Plus` if a condition does not hold, or
-- | succeed using `Applicative` if it does.
-- |
-- | For example:
-- |
-- | ```purescript
-- | import Prelude
-- | import Control.Alternative (guard)
-- | import Data.Array ((..))
-- |
-- | factors :: Int -> Array Int
-- | factors n = do
-- | a <- 1..n
-- | b <- 1..n
-- | guard $ a * b == n
-- | pure a
-- | ```
guard :: forall m. Alternative m => Boolean -> m Unit
guard true = pure unit
guard false = empty
13 changes: 8 additions & 5 deletions src/Control/MonadPlus.purs
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,23 @@ module Control.MonadPlus
) where

import Control.Alt (class Alt, alt, (<|>))
import Control.Alternative (class Alternative)
import Control.Alternative (class Alternative, guard)
import Control.Applicative (class Applicative, pure, liftA1, unless, when)
import Control.Apply (class Apply, apply, (*>), (<*), (<*>))
import Control.Bind (class Bind, bind, ifM, join, (<=<), (=<<), (>=>), (>>=))
import Control.Monad (class Monad, ap, liftM1)
import Control.MonadZero (class MonadZero, guard)
import Control.MonadZero (class MonadZero)
import Control.Plus (class Plus, empty)

import Data.Functor (class Functor, map, void, ($>), (<#>), (<$), (<$>))

-- | The `MonadPlus` type class has no members of its own but extends
-- | `MonadZero` with an additional law:
-- | The `MonadPlus` type class has no members of its own; it just specifies
-- | that the type has both `Monad` and `Alternative` instances.
-- |
-- | Types which have `MonadPlus` instances should also satisfy the following
-- | law:
-- |
-- | - Distributivity: `(x <|> y) >>= f == (x >>= f) <|> (y >>= f)`
class MonadZero m <= MonadPlus m
class (Monad m, Alternative m) <= MonadPlus m

instance monadPlusArray :: MonadPlus Array
42 changes: 14 additions & 28 deletions src/Control/MonadZero.purs
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
-- | This module is **deprecated** and will be removed in a future release.
-- |
-- | The annihilation law witnessed by `MonadZero` is trivially satisfied by
-- | lawful monads due to parametricity: while evaluating `empty >>= f`, the
-- | function `f` can’t ever be called, since that would require `empty` to
-- | produce a value, which means that `empty >>= f` must be the same as
-- | `empty >>= pure`, which by the monad laws is just `empty`.
-- |
-- | Use `Monad` and `Alternative` constraints instead.

module Control.MonadZero
( class MonadZero
, guard
, module Control.Alt
, module Control.Alternative
, module Control.Applicative
Expand All @@ -12,15 +21,16 @@ module Control.MonadZero
) where

import Control.Alt (class Alt, alt, (<|>))
import Control.Alternative (class Alternative)
import Control.Alternative (class Alternative, guard)
import Control.Applicative (class Applicative, pure, liftA1, unless, when)
import Control.Apply (class Apply, apply, (*>), (<*), (<*>))
import Control.Bind (class Bind, bind, ifM, join, (<=<), (=<<), (>=>), (>>=))
import Control.Monad (class Monad, ap, liftM1)
import Control.Plus (class Plus, empty)

import Data.Functor (class Functor, map, void, ($>), (<#>), (<$), (<$>))
import Data.Unit (Unit, unit)

import Prim.TypeError (class Warn, Text)

-- | The `MonadZero` type class has no members of its own; it just specifies
-- | that the type has both `Monad` and `Alternative` instances.
Expand All @@ -29,28 +39,4 @@ import Data.Unit (Unit, unit)
-- | laws:
-- |
-- | - Annihilation: `empty >>= f = empty`
class (Monad m, Alternative m) <= MonadZero m

instance monadZeroArray :: MonadZero Array

-- | Fail using `Plus` if a condition does not hold, or
-- | succeed using `Monad` if it does.
-- |
-- | For example:
-- |
-- | ```purescript
-- | import Prelude
-- | import Control.Monad (bind)
-- | import Control.MonadZero (guard)
-- | import Data.Array ((..))
-- |
-- | factors :: Int -> Array Int
-- | factors n = do
-- | a <- 1..n
-- | b <- 1..n
-- | guard $ a * b == n
-- | pure a
-- | ```
guard :: forall m. MonadZero m => Boolean -> m Unit
guard true = pure unit
guard false = empty
class (Monad m, Alternative m, Warn (Text "'MonadZero' is deprecated, use 'Monad' and 'Alternative' constraints instead")) <= MonadZero m