FP_HSE2020Fall_11pr
{-# LANGUAGE PartialTypeSignatures #-} | |
module Fp10pr where | |
import Control.Monad | |
import Control.Monad.Writer | |
--import Control.Monad.Reader | |
import Control.Monad.State | |
import Data.IORef | |
import System.Random | |
----------------------------------------- | |
-- Разминка | |
{- | |
GHCi> sequence [Just 1,Just 2,Just 3] | |
GHCi> sequence [Just 1,Just 2,Nothing,Just 4] | |
GHCi> sequence [[1,2,3],[10,20]] | |
GHCi> mapM (\x -> [x+1,x*2]) [10,20,30] | |
GHCi> sequence_ [[1,2,3],[10,20]] | |
GHCi> mapM_ (\x -> [x+1,x*2]) [10,20,30] | |
GHCi> forM_ [10,20,30] (\x -> [x+1,x*2]) | |
GHCi> let x = print "first" in print "second" | |
GHCi> let x = print "first" in x >> print "second" | |
GHCi> (\x -> print "first") (print "second") | |
GHCi> print "first" `seq` print "second" | |
-} | |
----------------------------------------------------- | |
-- Reader | |
newtype Reader r a = Reader { runReader :: r -> a } | |
reader :: (r -> a) -> Reader r a | |
reader = undefined | |
instance Functor (Reader r) where | |
fmap = undefined | |
instance Applicative (Reader r) where | |
pure = undefined | |
(<*>) = undefined | |
instance Monad (Reader r) where | |
return x = reader $ \e -> x | |
m >>= k = reader $ \e -> let v = runReader m e | |
in runReader (k v) e | |
ask :: Reader r r | |
ask = undefined | |
asks :: (r -> a) -> Reader r a | |
asks = undefined | |
local :: (r -> r) -> Reader r a -> Reader r a | |
local = undefined | |
local' :: (r -> r') -> _ | |
local' = undefined | |
{- | |
В mtl в настоящем Reader стандартный интерфейс | |
упакован в специальный класс типов. | |
Поэтому его может выставлять не только сам Reader, | |
но и любая Reader-подобная монада: | |
class Monad m => MonadReader r m | m -> r where | |
ask :: m r | |
local :: (r -> r) -> m a -> m a | |
reader :: (r -> a) -> m a -- конструирует не Reader, а что угодно Reader-подобное | |
reader f = do | |
r <- ask | |
return (f r) | |
asks :: MonadReader r m => (r -> a) -> m a | |
-} | |
----------------------------------------------------- | |
-- Writer | |
-- Рукописный логгер | |
data Logged a = Logged String a deriving (Eq,Show) | |
instance Functor Logged where | |
fmap = undefined | |
instance Applicative Logged where | |
pure = undefined | |
(<*>) = undefined | |
instance Monad Logged where | |
return = undefined | |
(>>=) = undefined | |
-- эквивалент tell | |
write2log :: String -> Logged () | |
write2log = undefined | |
logIt :: Show b => b -> Logged b | |
logIt v = do | |
write2log $ "var = " ++ show v ++ "; " | |
return v | |
test :: Logged Integer | |
test = do | |
x <- logIt 3 | |
y <- logIt 5 | |
let res = x + y | |
write2log $ "sum = " ++ show res ++ "; " | |
return res | |
{- | |
GHCi> test | |
Logged "sum = 8; var = 5; var = 3; " 8 | |
-} | |
----------------------------------------------------- | |
-- State | |
fac :: Int -> Integer | |
fac n = fst $ execState (replicateM n facStep) (1,0) | |
facStep :: State (Integer,Integer) () | |
facStep = do | |
undefined | |
fac' :: Integer -> Integer | |
fac' n = execState (forM_ [1..n] facStep') 1 | |
facStep' :: Integer -> State Integer () | |
facStep' i = undefined | |
{- | |
GHCi> fac 5 | |
120 | |
GHCi> fac' 5 | |
120 | |
GHCi> fac 33 | |
8683317618811886495518194401280000000 | |
GHCi> fac' 33 | |
8683317618811886495518194401280000000 | |
GHCi> product [1..33] | |
8683317618811886495518194401280000000 | |
-} | |
----------------------------------------------------- | |
-- IORef | |
testIORef :: IO [Integer] | |
testIORef = do | |
ref <- newIORef 1 | |
val1 <- readIORef ref | |
writeIORef ref 41 | |
val2 <- readIORef ref | |
modifyIORef' ref succ | |
val3 <- readIORef ref | |
return [val1,val2,val3] | |
{- | |
GHCi> testIORef | |
[1,41,42] | |
-} | |
fac'' :: Integer -> IO Integer | |
fac'' n = do | |
undefined | |
---------------------------------------- | |
-- Random | |
randomRState :: (Random a, RandomGen g) => (a, a) -> State g a | |
randomRState (x,y) = do | |
undefined | |
testWork :: ([Int],[Int]) | |
testWork = evalState doWork (mkStdGen 42) | |
doWork :: State StdGen ([Int],[Int]) | |
doWork = do | |
xs <- replicateM 5 $ randomRState (1,6) | |
ys <- replicateM 5 $ randomRState (1,6) | |
return (xs, ys) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment