Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- {-# LANGUAGE ExistentialQuantification #-}
- {-# LANGUAGE ExplicitForAll #-}
- {-# LANGUAGE FlexibleInstances #-}
- {-# LANGUAGE MultiParamTypeClasses #-}
- {-# LANGUAGE OverloadedStrings #-}
- {-# LANGUAGE ScopedTypeVariables #-}
- {-# LANGUAGE TupleSections #-}
- {-
- This is an exercise in learning Haskell. I wrote these mostly in a clean-room fashion
- as a way to figure out how to do monads, monad transformers, a Reader monad (RT) and
- a state monad (ST).
- -}
- module Main where
- import Control.Applicative
- import Control.Monad.Identity
- import Control.Monad.IO.Class
- import Control.Monad.Reader
- import Control.Monad.State
- import Control.Monad.Trans
- import Data.Monoid
- newtype RT r m a = RT { runRT :: r -> m a }
- instance Functor m => Functor (RT r m) where
- fmap f (RT a) = RT $ fmap f . a
- instance Applicative m => Applicative (RT r m) where
- pure = RT . const . pure
- (RT f) <*> (RT a) = RT $ \r -> (f r) <*> (a r)
- instance Monad m => Monad (RT r m) where
- return = pure
- (RT a) >>= f = RT $ \r -> do
- a' <- a r
- runRT (f a') r
- instance MonadTrans (RT r) where
- lift = RT . const
- instance MonadIO m => MonadIO (RT r m) where
- liftIO = lift . liftIO
- instance Monad m => MonadReader r (RT r m) where
- ask = RT return
- local t (RT a) = RT $ \r -> a (t r)
- type R r = RT r Identity
- runR :: R r a -> r -> a
- runR a = runIdentity . runRT a
- newtype ST s m a = ST { runST :: s -> m (a, s) }
- evalST a = fst . runST a
- execST a = snd . runST a
- instance Functor m => Functor (ST s m) where
- fmap f (ST a) = ST $ fmap (\(a', s') -> (f a', s')) . a
- instance Monad m => Applicative (ST s m) where
- pure a = ST $ pure . (a,)
- (ST f) <*> (ST a) = ST $ \s -> do
- ~(f', s') <- f s
- ~(a', s'') <- a s'
- return $ (f' a', s'')
- instance Monad m => Monad (ST s m) where
- return = pure
- (ST a) >>= f = ST $ \s -> do
- ~(a', s') <- (a s)
- runST (f a') s'
- instance Monad m => MonadState s (ST s m) where
- get = ST $ \s -> return (s, s)
- put s = ST $ \_ -> return ((), s)
- instance MonadTrans (ST s) where
- lift a = ST $ \s -> a >>= return . (,s)
- instance MonadIO m => MonadIO (ST s m) where
- liftIO = lift . liftIO
- type S s = ST s Identity
- runS :: S s a -> s -> (a, s)
- runS a = runIdentity . runST a
- evalS a = fst . runS a
- execS a = snd . runS a
- type RS a = RT a (S a) a
- runRS :: Int -> Int -> RS Int -> (Int, Int)
- runRS r s a = runS (runRT a r) s
- evalRS r s a = fst $ runRS r s a
- execRS r s a = snd $ runRS r s a
- x :: Int -> RT Int (S Int) Int
- x n = do
- r <- ask
- s <- lift $ do
- modify (+n)
- get
- return $ (n * n) + (r * s)
- main = print $ runS (runRT (liftA2 (+) (x 2) (x 1)) 2) 1
Add Comment
Please, Sign In to add comment