Uploaded by EruFilosifoMakar

5 Monady

advertisement
5.1 Класс типов Functor и законы для него
1. instance Functor Point3D where
fmap f (Point3D a b c) = Point3D (f a) (f b) (f c)
2. instance Functor GeomPrimitive where
fmap f (Point x) = Point (fmap f x)
fmap f (LineSegment x y) = LineSegment (fmap f x) (fmap f y)
3. instance Functor Tree where
fmap f (Leaf x) = Leaf (fmap f x)
fmap f (Branch l x r) = Branch (fmap f l) (fmap f x) (fmap f r)
4. instance Functor (Entry k1 k2) where
fmap f (Entry (k1, k2) v) = Entry (k1, k2) (f v)
instance Functor (Map k1 k2) where
fmap f (Map entries) = Map (map (fmap f) entries)
5.2 Определение монады
1. toLogger :: (a -> b) -> String -> (a -> Log b)
toLogger f msg = Log [msg] . f
execLoggers :: a -> (a -> Log b) -> (b -> Log c) -> Log c
execLoggers a f g = Log (logb ++ logc) c where
(Log logb b) = f a
(Log logc c) = g b
returnLog :: a -> Log a
returnLog = Log []
2. toLogger :: (a -> b) -> String -> (a -> Log b)
toLogger f msg = Log [msg] . f
execLoggers :: a -> (a -> Log b) -> (b -> Log c) -> Log c
execLoggers a f g = Log (logb ++ logc) c where
(Log logb b) = f a
(Log logc c) = g b
returnLog :: a -> Log a
returnLog = Log []
bindLog :: Log a -> (a -> Log b) -> Log b
bindLog (Log msga a) f = Log (msga ++ msgb) b where
(Log msgb b) = f a
3. хз
4. хз
5. хз
5.3 Монада Identity
1. хз
2. Не выполняется первый закон
Не выполняется второй закон
3. Все законы выполняются
4.
Не выполняется 1-й закон Не выполняется 3-й закон
5.4 Список и Maybe как монады
1.
import Data.Char (isDigit)
asToken :: String -> Maybe Token
asToken x = case x of
[] -> Nothing
"(" -> Just LeftBrace
")" -> Just RightBrace
"-" -> Just Minus
"+" -> Just Plus
_ | all isDigit x -> Just $ Number $ read x
| otherwise -> Nothing
tokenize :: String -> Maybe [Token]
tokenize = sequence . (map asToken) . words
2.
nextPositionsN :: Board -> Int -> (Board -> Bool) -> [Board]
nextPositionsN b n pred
| n < 0 = []
| n == 0 = filter pred [b]
| otherwise = do
move <- nextPositions b
restMoves <- nextPositionsN move (n - 1) pred
return restMoves
3.
pythagoreanTriple :: Int -> [(Int, Int, Int)]
pythagoreanTriple x
| x <= 0 = []
| otherwise = do
b <- [1..x]
a <- [1..b-1]
c <- [1..x]
True <- return $ (a^2 + b^2) == c^2
return (a,b,c)
5.5 Монада IO
1.
main' :: IO ()
main' = do
putStr $ "What is your name?\nName: "
name <- getLine
if null name
then main'
else putStrLn $ "Hi, " ++ name ++ "!"
2.
import Data.List (isInfixOf, filter)
import Control.Monad(liftM)
main' :: IO ()
main' = do
putStr $ "Substring: "
pattern <- getLine
if null pattern
then putStrLn "Canceled"
else getFiles pattern >>= mapM_ deleteFile
getFiles :: String -> IO [FilePath]
getFiles pattern =
liftM (filter (isInfixOf pattern)) $ getDirectoryContents "."
deleteFile :: FilePath -> IO ()
deleteFile path = do
putStrLn $ "Removing file: " ++ path
removeFile path
5.6 Монада Reader
1. 24
2. В сочетании с монадой Reader этот оператор бесполезен
3.
local' :: (r -> e) -> Reader e a -> Reader r a
4.
import Control.Monad (ap, liftM)
local' :: (r -> r') -> Reader r' a -> Reader r a
local' f m = Reader $ (runReader m) . f
5.
usersWithBadPasswords :: Reader UsersTable [User]
usersWithBadPasswords = asks $ map fst . filter isBad where
isBad = ("123456" ==) . snd
5.7 Монада Writer
1.
evalWriter :: Writer w a -> a
evalWriter = fst . runWriter
2.хз
3.
purchase :: String -> Integer -> Shopping
purchase _ cost = writer ((), Sum cost)
total :: Shopping -> Integer
total = getSum . execWriter
4.
type Shopping = Writer ([(String, Integer)]) ()
purchase :: String -> Integer -> Shopping
purchase item price = writer ((), [(item, price)])
total :: Shopping -> Integer
total = sum . (map snd) . execWriter
items :: Shopping -> [String]
items = (map fst) . execWriter
5.8 Монада State
1.
Монада Reader является частным случаем монады State
Монада Writer является частным случаем монады State
2. Монада State реализована в одном из пакетов Haskell Platform
3.
readerToState :: Reader r a -> State r a
readerToState m = state $ \e -> (runReader m e, e)
4.
writerToState :: Monoid w => Writer w a -> State w a
writerToState m = let
(a, w) = runWriter m
in state $ \e -> (a, e `mappend` w)
5.
fibStep :: State (Integer, Integer) ()
fibStep = do
(a, b) <- get
put (b, a + b)
execStateN :: Int -> State s a -> s -> s
execStateN n m = execState (replicateM n m)
6. хз
Download