vision-0.0.5.0: src/Control/Monad/EnvIO.hs
-- -*-haskell-*-
-- Vision (for the Voice): an XMMS2 client.
--
-- Author: Oleg Belozeorov
-- Created: 13 Jul. 2010
--
-- Copyright (C) 2011 Oleg Belozeorov
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License as
-- published by the Free Software Foundation; either version 3 of
-- the License, or (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- General Public License for more details.
--
{-# LANGUAGE MultiParamTypeClasses,
FunctionalDependencies,
FlexibleInstances,
UndecidableInstances #-}
module Control.Monad.EnvIO
( EnvM (..)
, envsx
, EnvIO (..)
, env
, runIn
, runIn'
) where
import Prelude hiding (catch)
import Control.Applicative
import Control.Monad.Trans
import Control.Monad.W
import Control.Monad.ToIO
import Control.Monad.CatchIO
import Data.Env
class (Monad m, MonadIO m) => EnvM ix a m | ix -> m a where
envx :: ix -> m a
newtype EnvIO e a = EnvIO { runEnvIO :: e -> IO a }
instance Functor (EnvIO e) where
f `fmap` m = EnvIO $ \e -> do
a <- runEnvIO m e
return $ f a
instance Monad (EnvIO e) where
return a = EnvIO $ const $ return a
m >>= n = EnvIO $ \e -> do
a <- runEnvIO m e
runEnvIO (n a) e
instance MonadIO (EnvIO e) where
liftIO = EnvIO . const
instance ToIO (EnvIO e) where
toIO = do
e <- env
return $ W $ flip runEnvIO e
instance MonadCatchIO (EnvIO e) where
m `catch` f = EnvIO $ \e ->
(runEnvIO m e)
`catch`
(\x -> runEnvIO (f x) e)
block = mapEnvIO block
unblock = mapEnvIO unblock
instance EnvX ix a e => EnvM ix a (EnvIO e) where
envx ix = extract ix <$> env
env :: EnvIO e e
env = EnvIO $ return
mapEnvIO :: (IO a -> IO b) -> EnvIO e a -> EnvIO e b
mapEnvIO f m = EnvIO $ f . runEnvIO m
runIn :: EnvB ix a e e' b => b -> EnvIO e (W (EnvIO e') IO)
runIn t =
runIn' $ flip build t
runIn' :: (e -> e') -> EnvIO e (W (EnvIO e') IO)
runIn' f = do
e <- env
return $ W $ \m ->
runEnvIO m $ f e
envsx :: EnvX ix a e => ix -> (a -> b) -> EnvIO e b
envsx ix acc = acc <$> envx ix