{-| Module : DeepControl.Monad.Trans.Except Description : Extension for mtl's Contrl.Monad.Except. Copyright : (C) 2013 Ross Paterson, (C) 2015 KONISHI Yohsuke License : BSD-style (see the file LICENSE) Maintainer : ocean0yohsuke@gmail.com Stability : experimental Portability : --- This module extended Except monad of mtl(monad-transformer-library). -} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE RankNTypes #-} module DeepControl.Monad.Trans.Except ( -- * Level-1 module Control.Monad.Except, -- * Level-2 throwError2, catchError2, -- * Level-3 throwError3, catchError3, -- * Level-4 throwError4, catchError4, -- * Level-5 throwError5, catchError5, ) where import DeepControl.Applicative import DeepControl.Monad import DeepControl.Commutative import Control.Monad.Except import Control.Monad.Identity ---------------------------------------------------------------- -- Level-1 instance Commutative (Except e) where commute x = ExceptT . Identity |$> commute (runExcept x) instance Monad2 (Except e) where m >>== f = (ExceptT . Identity |$>) $ (runExcept |$> m) >>== runExcept |$>> f instance Monad3 (Except e) where m >>>== f = (ExceptT . Identity |$>>) $ (runExcept |$>> m) >>>== runExcept |$>>> f instance Monad4 (Except e) where m >>>>== f = (ExceptT . Identity |$>>>) $ (runExcept |$>>> m) >>>>== runExcept |$>>>> f instance Monad5 (Except e) where m >>>>>== f = (ExceptT . Identity |$>>>>) $ (runExcept |$>>>> m) >>>>>== runExcept |$>>>>> f ---------------------------------------------------------------- -- Level-2 throwError2 :: (MonadError e m2, Applicative m1) => e -> m1 (m2 a) throwError2 = (*:) |$> throwError catchError2 :: (MonadError e m2, Commutative m1, Commutative m2) => m1 (m2 a) -> (e -> m1 (m2 a)) -> m1 (m2 a) catchError2 = coverCatch catchError where coverCatch :: (Commutative m1, Commutative m2) => (forall a. m2 a -> (e -> m2 a) -> m2 a) -> m1 (m2 a) -> (e -> m1 (m2 a)) -> m1 (m2 a) coverCatch catch m h = let m' = commute m h' = commute |$> h in commute $ catch m' h' ---------------------------------------------------------------- -- Level-3 throwError3 :: (MonadError e m3, Applicative m1, Applicative m2) => e -> m1 (m2 (m3 a)) throwError3 = (**:) |$> throwError catchError3 :: (MonadError e m3, Commutative m1, Commutative m2, Commutative m3) => m1 (m2 (m3 a)) -> (e -> m1 (m2 (m3 a))) -> m1 (m2 (m3 a)) catchError3 = cover2Catch catchError where cover2Catch :: (Commutative m1, Commutative m2, Commutative m3) => (forall a. m3 a -> (e -> m3 a) -> m3 a) -> m1 (m2 (m3 a)) -> (e -> m1 (m2 (m3 a))) -> m1 (m2 (m3 a)) cover2Catch catch m h = let m' = float2 m h' = float2 |$> h in sink2 $ catch m' h' ---------------------------------------------------------------- -- Level-4 throwError4 :: (MonadError e m4, Applicative m1, Applicative m2, Applicative m3) => e -> m1 (m2 (m3 (m4 a))) throwError4 = (***:) |$> throwError catchError4 :: (MonadError e m4, Commutative m1, Commutative m2, Commutative m3, Commutative m4) => m1 (m2 (m3 (m4 a))) -> (e -> m1 (m2 (m3 (m4 a)))) -> m1 (m2 (m3 (m4 a))) catchError4 = cover3Catch catchError where cover3Catch :: (Commutative m1, Commutative m2, Commutative m3, Commutative m4) => (forall a. m4 a -> (e -> m4 a) -> m4 a) -> m1 (m2 (m3 (m4 a))) -> (e -> m1 (m2 (m3 (m4 a)))) -> m1 (m2 (m3 (m4 a))) cover3Catch catch m h = let m' = float3 m h' = float3 |$> h in sink3 $ catch m' h' ---------------------------------------------------------------- -- Level-5 throwError5 :: (MonadError e m5, Applicative m1, Applicative m2, Applicative m3, Applicative m4) => e -> m1 (m2 (m3 (m4 (m5 a)))) throwError5 = (****:) |$> throwError catchError5 :: (MonadError e m5, Commutative m1, Commutative m2, Commutative m3, Commutative m4, Commutative m5) => m1 (m2 (m3 (m4 (m5 a)))) -> (e -> m1 (m2 (m3 (m4 (m5 a))))) -> m1 (m2 (m3 (m4 (m5 a)))) catchError5 = cover4Catch catchError where cover4Catch :: (Commutative m1, Commutative m2, Commutative m3, Commutative m4, Commutative m5) => (forall a. m5 a -> (e -> m5 a) -> m5 a) -> m1 (m2 (m3 (m4 (m5 a)))) -> (e -> m1 (m2 (m3 (m4 (m5 a))))) -> m1 (m2 (m3 (m4 (m5 a)))) cover4Catch catch m h = let m' = float4 m h' = float4 |$> h in sink4 $ catch m' h' ---------------------------------------------------------------- -- Level-6 {- cover5Catch :: (Commutative m1, Commutative m2, Commutative m3, Commutative m4, Commutative m5, Commutative m6) => (forall a. m6 a -> (e -> m6 a) -> m6 a) -> m1 (m2 (m3 (m4 (m5 (m6 a))))) -> (e -> m1 (m2 (m3 (m4 (m5 (m6 a)))))) -> m1 (m2 (m3 (m4 (m5 (m6 a))))) cover5Catch catch m h = let m' = float5 m h' = float5 |$> h in sink5 $ catch m' h' -}