Commit 8c80dcc1 authored by Herbert Valerio Riedel's avatar Herbert Valerio Riedel 🕺

base: Add new Control.Monad.Fail module (re #10751)

This is based on David's initial patch augmented by more extensive
Haddock comments.

This has been broken out of D1248 to reduce its size
by splitting the patch into smaller logical pieces.

On its own, this new module does nothing interesting yet.
Later patches will add support for a different desugaring of
`do`-blocks, at which point the new `MonadFail` class will
become more useful.

Reviewed By: ekmett, austin

Differential Revision: https://phabricator.haskell.org/D1424
parent 83fd2baf
{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE NoImplicitPrelude #-}
-- |
-- Module : Control.Monad.Fail
-- Copyright : (C) 2015 David Luposchainsky,
-- (C) 2015 Herbert Valerio Riedel
-- License : BSD-style (see the file LICENSE)
--
-- Maintainer : libraries@haskell.org
-- Stability : provisional
-- Portability : portable
--
-- Transitional module providing the 'MonadFail' class and primitive
-- instances.
--
-- This module can be imported for defining forward compatible
-- 'MonadFail' instances:
--
-- @
-- import qualified Control.Monad.Fail as Fail
--
-- instance Monad Foo where
-- (>>=) = {- ...bind impl... -}
--
-- -- Provide legacy 'fail' implementation for when
-- -- new-style MonadFail desugaring is not enabled.
-- fail = Fail.fail
--
-- instance Fail.MonadFail Foo where
-- fail = {- ...fail implementation... -}
-- @
--
-- See <https://wiki.haskell.org/MonadFail_Proposal> for more details.
--
-- @since 4.9.0.0
--
module Control.Monad.Fail ( MonadFail(fail) ) where
import GHC.Base (String, Monad(), Maybe(Nothing), IO())
import {-# SOURCE #-} GHC.IO (failIO)
-- | When a value is bound in @do@-notation, the pattern on the left
-- hand side of @<-@ might not match. In this case, this class
-- provides a function to recover.
--
-- A 'Monad' without a 'MonadFail' instance may only be used in conjunction
-- with pattern that always match, such as newtypes, tuples, data types with
-- only a single data constructor, and irrefutable patterns (@~pat@).
--
-- Instances of 'MonadFail' should satisfy the following law: @fail s@ should
-- be a left zero for '>>=',
--
-- @
-- fail s >>= f = fail s
-- @
--
-- If your 'Monad' is also 'MonadPlus', a popular definition is
--
-- @
-- fail _ = mzero
-- @
--
-- @since 4.9.0.0
class Monad m => MonadFail m where
fail :: String -> m a
instance MonadFail Maybe where
fail _ = Nothing
instance MonadFail [] where
{-# INLINE fail #-}
fail _ = []
instance MonadFail IO where
fail = failIO
......@@ -479,6 +479,11 @@ class Applicative m => Monad m where
-- | Fail with a message. This operation is not part of the
-- mathematical definition of a monad, but is invoked on pattern-match
-- failure in a @do@ expression.
--
-- As part of the MonadFail proposal (MFP), this function is moved
-- to its own class 'MonadFail' (see "Control.Monad.Fail" for more
-- details). The definition here will be removed in a future
-- release.
fail :: String -> m a
fail s = error s
......
......@@ -113,6 +113,7 @@ Library
Control.Exception
Control.Exception.Base
Control.Monad
Control.Monad.Fail
Control.Monad.Fix
Control.Monad.Instances
Control.Monad.IO.Class
......
......@@ -62,6 +62,9 @@
* New module `Control.Monad.IO.Class` (previously provided by `transformers`
package). (#10773)
* New module `Control.Monad.Fail` providing new `MonadFail(fail)`
class (#10751)
* The `Generic` instance for `Proxy` is now poly-kinded (#10775)
* add `Data.List.NonEmpty` and `Data.Semigroup` (to become
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment