env.hs
import Control.Applicative
type Env = String
newtype F a = F (Env -> a)
onEnv :: (Env -> a) -> F a
onEnv = F
runOnEnv :: F a -> Env -> a
runOnEnv (F f) = f
instance Functor F where
fmap f x = onEnv $ \env -> f (x `runOnEnv` env)
instance Applicative F where
-- pure :: a -> F a
pure x = onEnv $ \env -> x
-- (<*>) :: F (a -> b) -> F a -> F b
f <*> a = onEnv $ \env -> (f `runOnEnv` env) (a `runOnEnv` env)
instance Monad F where
-- return :: a -> F a
return = pure
-- (>>=) :: F a -> (a -> F b) -> F b
m >>= k = onEnv $ \env -> k (runOnEnv m env) `runOnEnv` env
count char = sum . map (fromEnum . (char==))
main = print $ runOnEnv ex "Hey, I'm an environment!" where
ex = do
n <- onEnv $ length
m <- onEnv $ count 'e'
p <- onEnv $ count ' '
return (n + m, n * m, p)