{-# LANGUAGE AllowAmbiguousTypes #-}
module Polysemy.Fail
(
Fail(..)
, runFail
, failToError
, failToNonDet
, failToEmbed
) where
import Control.Applicative
import Polysemy
import Polysemy.Fail.Type
import Polysemy.Error
import Polysemy.NonDet
import Control.Monad.Fail as Fail
runFail :: Sem (Fail ': r) a
-> Sem r (Either String a)
runFail = runError . reinterpret (\(Fail s) -> throw s)
{-# INLINE runFail #-}
failToError :: Member (Error e) r
=> (String -> e)
-> Sem (Fail ': r) a
-> Sem r a
failToError f = interpret $ \(Fail s) -> throw (f s)
{-# INLINE failToError #-}
failToNonDet :: Member NonDet r
=> Sem (Fail ': r) a
-> Sem r a
failToNonDet = interpret $ \(Fail _) -> empty
{-# INLINE failToNonDet #-}
failToEmbed :: forall m r a
. (Member (Embed m) r, MonadFail m)
=> Sem (Fail ': r) a
-> Sem r a
failToEmbed = interpret $ \(Fail s) -> embed @m (Fail.fail s)
{-# INLINE failToEmbed #-}