Skip to content

Instantly share code, notes, and snippets.

@deniok

deniok/Fp11pr.hs Secret

Created Nov 25, 2020
Embed
What would you like to do?
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