{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} module Data.Aviation.Aip.AipCon( AipCon(..) ) where import Control.Category((.)) import Control.Applicative(Applicative(pure, (<*>))) import Control.Lens import Control.Monad(Monad(return, (>>=))) import Control.Monad.Catch(MonadThrow(throwM), MonadCatch(catch)) import Control.Monad.IO.Class(MonadIO(liftIO)) import Control.Monad.Trans.Except(ExceptT) import Data.Aviation.Aip.ConnErrorHttp4xx(ConnErrorHttp4xx) import Data.Bool(Bool) import Data.Functor(Functor(fmap)) import System.IO(IO) newtype AipCon a = AipCon (Bool -> ExceptT ConnErrorHttp4xx IO a) instance AipCon a ~ r => Rewrapped (AipCon b) r instance Wrapped (AipCon x) where type Unwrapped (AipCon x) = Bool -> ExceptT ConnErrorHttp4xx IO x _Wrapped' = iso (\(AipCon x) -> x) AipCon instance Functor AipCon where fmap f (AipCon x) = AipCon (fmap (fmap f) x) instance Applicative AipCon where pure = AipCon . pure . pure AipCon f <*> AipCon a = AipCon (\b -> f b <*> a b) instance Monad AipCon where return = pure AipCon x >>= f = AipCon (\b -> x b >>= \a -> let r = f a ^. _Wrapped in r b) instance MonadIO AipCon where liftIO = AipCon . pure . liftIO instance MonadThrow AipCon where throwM e = AipCon (\_ -> throwM e) instance MonadCatch AipCon where catch (AipCon x) k = AipCon (\b -> catch (x b) (\z -> let r = k z ^. _Wrapped in r b))