Advertisement
NLinker

MaybeT from zero to hero

Feb 19th, 2020
923
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- http://cmsc-16100.cs.uchicago.edu/2018-autumn/ExtraNotes/monad-transformers/
  2.  
  3. module MaybeT where
  4.  
  5. import Control.Applicative
  6. import Control.Monad
  7. import Control.Monad.Trans.Class
  8. import Data.Char
  9.  
  10. readInt0 :: IO (Maybe Int)
  11. readInt0 = do
  12.   s <- getLine
  13.   if all isDigit s
  14.     then pure $ Just (read s)
  15.     else pure Nothing
  16.  
  17. readInt :: IO (Maybe Int)
  18. readInt = do
  19.   s <- getLine
  20.   pure $ do
  21.     guard (all isDigit s)
  22.     Just (read s)
  23.  
  24. addThree0 :: IO (Maybe Int)
  25. addThree0 = do
  26.   mi <- readInt
  27.   mj <- readInt
  28.   mk <- readInt
  29.   case (mi, mj, mk) of
  30.     (Just i, Just j, Just k) -> pure $ Just (i+j+k)
  31.     _                        -> pure Nothing
  32.  
  33. addThree1 :: IO (Maybe Int)
  34. addThree1 = do
  35.   mi <- readInt
  36.   mj <- readInt
  37.   mk <- readInt
  38.   pure $ do
  39.     i <- mi
  40.     j <- mj
  41.     k <- mk
  42.     pure $ i + j + k
  43.  
  44. addThree2 :: IO (Maybe Int)
  45. addThree2 = do
  46.   mi <- readInt
  47.   case mi of
  48.     Nothing -> pure Nothing
  49.     Just i  -> do
  50.       mj <- readInt
  51.       case mj of
  52.         Nothing -> pure Nothing
  53.         Just j -> do
  54.           mk <- readInt
  55.           case mk of
  56.             Nothing -> pure Nothing
  57.             Just k  -> pure $ Just (i+j+k)
  58.  
  59. bindMonadPlusMaybe :: Monad m => m (Maybe a) -> (a -> m (Maybe b)) -> m (Maybe b)
  60. action `bindMonadPlusMaybe` f = do
  61.   ma <- action
  62.   case ma of
  63.     Nothing -> pure Nothing
  64.     Just a  -> f a
  65.  
  66. pureMonadPlusMaybe :: Monad m => a -> m (Maybe a)
  67. pureMonadPlusMaybe a = pure $ Just a
  68.  
  69. addThree :: IO (Maybe Int)
  70. addThree =
  71.   readInt `bindMonadPlusMaybe` \i ->
  72.   readInt `bindMonadPlusMaybe` \j ->
  73.   readInt `bindMonadPlusMaybe` \k ->
  74.   pureMonadPlusMaybe (i+j+k)
  75.  
  76. ----------------------------------------------------------------------
  77.  
  78. newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
  79.  
  80. instance Monad m => Monad (MaybeT m) where
  81.  -- return :: a -> MaybeT m a
  82.     return = MaybeT . return . Just
  83.  
  84.  -- (>>=) :: MaybeT m a -> (a -> MaybeT m b) -> MaybeT m b
  85.     MaybeT mma >>= f = MaybeT $ do
  86.       ma <- mma
  87.       case ma of
  88.         Nothing -> pure Nothing
  89.         Just a  -> runMaybeT $ f a
  90.  
  91. instance Monad m => Functor (MaybeT m) where
  92.     fmap f x = pure f <*> x
  93.  
  94. instance Monad m => Applicative (MaybeT m) where
  95.     pure = return
  96.     (<*>) = ap
  97.  
  98. instance MonadTrans MaybeT where
  99.  -- lift :: Monad m => m a -> MaybeT m a
  100.  -- lift = liftMaybeT
  101.  -- lift ma = MaybeT (fmap Just ma)
  102.     lift = MaybeT . fmap Just
  103.  
  104. instance (Monad m, Alternative m) => Alternative (MaybeT m) where
  105.  -- empty :: MaybeT m a
  106.     empty = MaybeT empty
  107.  
  108.  -- (<|>) :: MaybeT m a -> MaybeT m a -> MaybeT m a
  109.     MaybeT mma <|> MaybeT mmb = MaybeT $ mma <|> mmb
  110.  
  111. ----------------------------------------------------------------------
  112.  
  113.  
  114. liftMaybeT :: Monad m => m a -> MaybeT m a
  115. liftMaybeT ma = MaybeT (fmap Just ma)
  116.  
  117. guardMaybeT :: Monad m => Bool -> MaybeT m ()
  118. guardMaybeT True  = MaybeT $ pure $ Just ()
  119. guardMaybeT False = MaybeT $ pure Nothing
  120.  
  121. maybeReadInt0 :: MaybeT IO Int
  122. maybeReadInt0 = do
  123.   s <- liftMaybeT getLine
  124.   if all isDigit s
  125.     then pure $ read s
  126.     else MaybeT $ pure Nothing
  127.  
  128. maybeAddThree0 :: MaybeT IO Int
  129. maybeAddThree0 = do
  130.   i <- maybeReadInt0
  131.   j <- maybeReadInt0
  132.   k <- maybeReadInt0
  133.   pure $ i+j+k
  134.  
  135. maybeReadInt1 :: MaybeT IO Int
  136. maybeReadInt1 = do
  137.   s <- liftMaybeT getLine
  138.   guardMaybeT $ all isDigit s
  139.   pure $ read s
  140.  
  141. maybeReadInt :: MaybeT IO Int
  142. maybeReadInt = do
  143.   s <- lift getLine
  144.   guard $ all isDigit s
  145.   pure $ read s
  146.  
  147. maybeAddThree :: MaybeT IO Int
  148. maybeAddThree = do
  149.   i <- maybeReadInt
  150.   j <- maybeReadInt
  151.   k <- maybeReadInt
  152.   pure $ i+j+k
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement