-
-
Save deniok/ed5bf340a97fe4f09468192fea0636bb to your computer and use it in GitHub Desktop.
FP_HSE2020Fall_11pr
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 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