{- | The `ArrowKleisli' type class allows for embedding monadic operations in Kleisli arrows. -} {-# LANGUAGE TypeOperators , MultiParamTypeClasses , FlexibleInstances , FunctionalDependencies #-} module Control.Arrow.ArrowKleisli where import Control.Arrow import Control.Category import Control.Monad.Trans import Prelude hiding ((.), id) class (Monad m, Arrow (~>)) => ArrowKleisli m (~>) | (~>) -> m where arrM :: (a -> m b) -> a ~> b instance Monad m => ArrowKleisli m (Kleisli m) where arrM f = Kleisli f constM :: ArrowKleisli m (~>) => m b -> a ~> b constM a = arrM (const a) effect :: ArrowKleisli m (~>) => m () -> a ~> a effect a = arrM (\b -> a >> return b) arrIO :: (MonadIO m, ArrowKleisli m (~>)) => (a -> IO b) -> a ~> b arrIO f = arrM (liftIO . f)