[Haskell-cafe] Applicative and Monad transformers
Jeremy Shaw
jeremy at n-heptane.com
Wed Aug 26 11:48:55 EDT 2009
Attached is as slight better test example which does not rely on the
'fail' method. Doesn't really change anything significant though.
-------------- next part --------------
{-# LANGUAGE FlexibleContexts, FlexibleInstances #-}
module Main where
import Control.Applicative (Applicative((<*>), pure), (<$>))
import Control.Monad (Monad((>>=), return), ap)
import Control.Monad.Reader (MonadReader(ask, local), ReaderT(ReaderT, runReaderT), mapReaderT)
import Data.Monoid(Monoid(mappend))
{-
instance (Monad f, Applicative f) => Applicative (ReaderT r f) where
pure = return
(<*>) = ap
-}
instance (Monad f, Applicative f) => Applicative (ReaderT r f) where
pure a = ReaderT $ const (pure a)
f <*> a = ReaderT $ \r ->
((runReaderT f r) <*> (runReaderT a r))
instance (Monoid e) => Applicative (Either e) where
pure = Right
(Left errF) <*> (Left errA) = Left (errF `mappend` errA)
(Left err) <*> _ = Left err
_ <*> (Left err) = Left err
(Right f) <*> (Right a) = Right (f a)
instance Monad (Either e) where
return = Right
(Right a) >>= f = f a
(Left e) >>= f = (Left e)
-- fail str = Left [str]
lookupE :: (Eq a) => a -> [(a,b)] -> (Either a b)
lookupE a env =
case lookup a env of
Just b -> Right b
Nothing -> Left a
look :: (Eq a) => a -> ReaderT [(a,b)] (Either [a]) b
look a =
do env <- ask
case lookup a env of
(Just b) -> return b
Nothing -> asLeft a
asLeft :: a -> ReaderT r (Either [a]) b
asLeft a =
mapReaderT (\m -> case m of
(Left as) -> Left (a:as)
(Right _) -> Left [a])
(return ())
looker :: ReaderT [(String, Int)] (Either [String]) (Int, Int, Int)
looker = ((,,) <$> look "foo" <*> look "bar" <*> look "baz")
test :: Either [String] (Int, Int, Int)
test =
runReaderT looker [("bar", 1)]
More information about the Haskell-Cafe
mailing list