graphted-0.3.0.0: src/Control/MonadFail/Graph.hs
{- |
Module : Control.MonadFail.Graph
Description : Graph indexed monads with failure.
Copyright : (c) Aaron Friel
License : BSD-3
Maintainer : Aaron Friel <mayreply@aaronfriel.com>
Stability : unstable
Portability : portable
This is only used in Do Notation with refutable patterns. e.g.:
@
do Just a <- m
k a
@
Is desugared as:
@
let f (Just a) = k a
f _ = fail "Pattern match failure in do expression..."
in m >>= k
@
With @-XApplicativeDo@, there are two outstanding issues:
__First__, This will not compile (https://ghc.haskell.org/trac/ghc/ticket/13648) as
the body statements @m1@ and @m2@ are desugared incorrectly:
@
f m1 m2 k = do
m1
m2
k
@
To resolve, replace @m1@ with @_ <- m1@.
__Second__, @'fail'@ must be in scope (https://ghc.haskell.org/trac/ghc/ticket/13649)
when wildcard patterns are used. The module "Prelude.Graphted" takes care of
this, and custom preludes must as well. A @'GMonadFail'@ constraint will not
be added unless a refutable pattern is used.
-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}
-- For the default Apply, Then, and But instances.
{-# LANGUAGE UndecidableInstances #-}
module Control.MonadFail.Graph where
import Control.Graphted.Class
import Control.Monad.Graph
import Control.MonadZero.Graph
-- | Graph indexed monad with failure.
class GMonad m => GMonadFail (m :: p -> * -> *) where
-- | The unit failure element of the index.
--
-- Default instance: @Fail m = 'Unit' m@
type family Fail m :: p
type instance Fail m = Unit m
-- | Fail with a message.
--
-- Default implementation requires the default instance of 'Fail'.
{-# INLINE gfail #-}
gfail :: String -> m (Fail m) a
default gfail :: (GMonadZero m, Zero m ~ Fail m) => String -> m (Fail m) a
gfail _ = gzero