Skip to content

Commit 9132ec9

Browse files
authored
Deprecate MonadZero (#64)
1 parent 185c084 commit 9132ec9

File tree

3 files changed

+45
-33
lines changed

3 files changed

+45
-33
lines changed

src/Control/Alternative.purs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module Control.Alternative
22
( class Alternative
3+
, guard
34
, module Control.Alt
45
, module Control.Applicative
56
, module Control.Apply
@@ -12,6 +13,7 @@ import Control.Applicative (class Applicative, pure, liftA1, unless, when)
1213
import Control.Apply (class Apply, apply, (*>), (<*), (<*>))
1314
import Control.Plus (class Plus, empty)
1415

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

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

2729
instance alternativeArray :: Alternative Array
30+
31+
-- | Fail using `Plus` if a condition does not hold, or
32+
-- | succeed using `Applicative` if it does.
33+
-- |
34+
-- | For example:
35+
-- |
36+
-- | ```purescript
37+
-- | import Prelude
38+
-- | import Control.Alternative (guard)
39+
-- | import Data.Array ((..))
40+
-- |
41+
-- | factors :: Int -> Array Int
42+
-- | factors n = do
43+
-- | a <- 1..n
44+
-- | b <- 1..n
45+
-- | guard $ a * b == n
46+
-- | pure a
47+
-- | ```
48+
guard :: forall m. Alternative m => Boolean -> m Unit
49+
guard true = pure unit
50+
guard false = empty

src/Control/MonadPlus.purs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,23 @@ module Control.MonadPlus
1212
) where
1313

1414
import Control.Alt (class Alt, alt, (<|>))
15-
import Control.Alternative (class Alternative)
15+
import Control.Alternative (class Alternative, guard)
1616
import Control.Applicative (class Applicative, pure, liftA1, unless, when)
1717
import Control.Apply (class Apply, apply, (*>), (<*), (<*>))
1818
import Control.Bind (class Bind, bind, ifM, join, (<=<), (=<<), (>=>), (>>=))
1919
import Control.Monad (class Monad, ap, liftM1)
20-
import Control.MonadZero (class MonadZero, guard)
20+
import Control.MonadZero (class MonadZero)
2121
import Control.Plus (class Plus, empty)
2222

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

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

3134
instance monadPlusArray :: MonadPlus Array

src/Control/MonadZero.purs

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
1+
-- | This module is **deprecated** and will be removed in a future release.
2+
-- |
3+
-- | The annihilation law witnessed by `MonadZero` is trivially satisfied by
4+
-- | lawful monads due to parametricity: while evaluating `empty >>= f`, the
5+
-- | function `f` can’t ever be called, since that would require `empty` to
6+
-- | produce a value, which means that `empty >>= f` must be the same as
7+
-- | `empty >>= pure`, which by the monad laws is just `empty`.
8+
-- |
9+
-- | Use `Monad` and `Alternative` constraints instead.
10+
111
module Control.MonadZero
212
( class MonadZero
3-
, guard
413
, module Control.Alt
514
, module Control.Alternative
615
, module Control.Applicative
@@ -12,15 +21,16 @@ module Control.MonadZero
1221
) where
1322

1423
import Control.Alt (class Alt, alt, (<|>))
15-
import Control.Alternative (class Alternative)
24+
import Control.Alternative (class Alternative, guard)
1625
import Control.Applicative (class Applicative, pure, liftA1, unless, when)
1726
import Control.Apply (class Apply, apply, (*>), (<*), (<*>))
1827
import Control.Bind (class Bind, bind, ifM, join, (<=<), (=<<), (>=>), (>>=))
1928
import Control.Monad (class Monad, ap, liftM1)
2029
import Control.Plus (class Plus, empty)
2130

2231
import Data.Functor (class Functor, map, void, ($>), (<#>), (<$), (<$>))
23-
import Data.Unit (Unit, unit)
32+
33+
import Prim.TypeError (class Warn, Text)
2434

2535
-- | The `MonadZero` type class has no members of its own; it just specifies
2636
-- | that the type has both `Monad` and `Alternative` instances.
@@ -29,28 +39,4 @@ import Data.Unit (Unit, unit)
2939
-- | laws:
3040
-- |
3141
-- | - Annihilation: `empty >>= f = empty`
32-
class (Monad m, Alternative m) <= MonadZero m
33-
34-
instance monadZeroArray :: MonadZero Array
35-
36-
-- | Fail using `Plus` if a condition does not hold, or
37-
-- | succeed using `Monad` if it does.
38-
-- |
39-
-- | For example:
40-
-- |
41-
-- | ```purescript
42-
-- | import Prelude
43-
-- | import Control.Monad (bind)
44-
-- | import Control.MonadZero (guard)
45-
-- | import Data.Array ((..))
46-
-- |
47-
-- | factors :: Int -> Array Int
48-
-- | factors n = do
49-
-- | a <- 1..n
50-
-- | b <- 1..n
51-
-- | guard $ a * b == n
52-
-- | pure a
53-
-- | ```
54-
guard :: forall m. MonadZero m => Boolean -> m Unit
55-
guard true = pure unit
56-
guard false = empty
42+
class (Monad m, Alternative m, Warn (Text "'MonadZero' is deprecated, use 'Monad' and 'Alternative' constraints instead")) <= MonadZero m

0 commit comments

Comments
 (0)