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. хз