Last active
December 5, 2021 12:27
-
-
Save ahaxu/b06ca4be5ebeb888e3f4c7b7d94a5d9e to your computer and use it in GitHub Desktop.
ReaderT excercises
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE NoImplicitPrelude #-} | |
{-# LANGUAGE InstanceSigs #-} | |
module ExMonadTrans1 where | |
-- Todo | |
-- implement eitherT | |
-- implement readerT | |
-- implement stateT | |
-- implement maybeT | |
-- monad transformer in real world | |
import Control.Monad | |
import Control.Applicative | |
import Data.Maybe | |
import Prelude ( | |
($) | |
, (<$>) | |
, undefined | |
, (.) | |
, (++) | |
, IO | |
, String | |
, putStrLn | |
, getLine | |
, (==) | |
, elem | |
, (&&) | |
, (||) | |
, (<) | |
, length | |
) | |
newtype ReaderT r m a = | |
ReaderT { | |
runReaderT :: r -> m a | |
} | |
instance (Functor m) => Functor (ReaderT r m) where | |
fmap :: (a -> b) | |
-> ReaderT r m a | |
-> ReaderT r m b | |
-- f = fmap :: a -> b -> f a -> f b :: A -> B (A:: a ->b, B :: f a -> f b) | |
-- g = fmap :: x -> y -> k x -> k y :: B -> C (B:: x -> y, C:: k x -> k y) | |
-- g . f :: (B->C) -> (A->B) -> A -> C ==> f a :: x and f b :: y | |
-- g . f :: A -> C :: (a->b) -> k f a -> k f b | |
fmap f (ReaderT rma) = ReaderT $ | |
--let | |
-- x = (fmap . fmap) f rma -- rma :: (((->) r) m) a | |
--in x | |
do | |
ma <- rma | |
return $ f <$> ma | |
instance (Applicative m) => Applicative (ReaderT r m) where | |
pure = ReaderT . pure . pure | |
(<*>) :: ReaderT r m (a -> b) | |
-> ReaderT r m a | |
-> ReaderT r m b | |
--(<*>) (ReaderT rmf) (ReaderT rma) = ReaderT $ | |
-- do | |
-- ma <- rma | |
-- f <- rmf | |
-- return $ f <*> ma | |
-- (<*>) <$> rmf :: ?? | |
-- rmf :: r -> m f :: r -> m (a ->b) :: (->r) m (a -> b) :: (->r) k , with k = m (a->b) | |
-- (<*>):: m (a -> b) -> (m a -> m b) :: k-> h , with h = m a -> m b | |
-- (<*>) <$> rmf :: (k -> h) -> (->r) k :: (->r) h :: (->r) (m a -> m b) (1) | |
-- rma :: (->r) m a (2) | |
-- (1) <*> (2) :: (->r) m b | |
(ReaderT rmf) <*> (ReaderT rma) = | |
ReaderT $ (<*>) <$> rmf <*> rma | |
instance (Monad m) => Monad (ReaderT r m) where | |
return = pure | |
(>>=) :: ReaderT r m a | |
-> (a -> ReaderT r m b) | |
-> ReaderT r m b | |
(>>=) (ReaderT rma) f = ReaderT $ | |
\r -> do | |
a <- rma r | |
let | |
rmb = runReaderT $ f a | |
rmb r | |
getName :: String -> IO (Maybe String) | |
getName input = do | |
putStrLn input | |
name <- getLine | |
if name == "" | |
then return Nothing | |
else return $ Just name | |
newtype MaybeT m a = MaybeT { | |
runMaybeT :: m (Maybe a) | |
} | |
getPass :: String -> IO (Maybe String) | |
getPass input = do | |
putStrLn input | |
pwd <- getLine | |
if (pwd == "") || (length pwd < 8) | |
then return Nothing | |
else return $ Just pwd | |
login :: IO (Maybe String) | |
login = do | |
name <- getName "type ur name" | |
case name of | |
Nothing -> return Nothing | |
Just n -> do | |
pwd <- getPass "type ur pass" | |
case pwd of | |
Nothing -> return Nothing | |
Just p -> return $ Just $ "name: " ++ n ++ " pass " ++ p | |
main :: IO () | |
main = do | |
creds <- login | |
case creds of | |
Nothing -> putStrLn "smt wrong !" | |
Just info -> putStrLn info | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment