{- | 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