首页 > 解决方案 > 我如何回答第 18 章,练习 5,来自第一原理的 Haskell,而不是练习 6 中的“flipType”

问题描述

练习是定义函数meh,我做了如下:

meh :: Monad m => [a] -> (a -> m b) -> m [b]
meh input_list transform = concatMonads transformed_input
  where 
    transformed_input = fmap transform input_list

concatMonads :: Monad m => [m b] -> m [b]
concatMonads [] = pure []
concatMonads (first:rest) = (concatMonads rest) >>= (appendListToMonadContent first)

appendListToMonadContent :: Monad m => m b -> [b] -> m [b]
appendListToMonadContent cur to_append = fmap (\first -> first:to_append) cur

下一个练习是定义flipType :: Monad m => [m b] -> m [b],提示是“重用meh”(这很简单:)flipType l = meh l id。但是,我对问题 5 的回答使用flipType了 ,它只是被称为concatMonads,所以很明显我的做法与作者的意图不同。

meh不使用如何定义flipType

标签: haskell

解决方案


meh :: Monad m => [a] -> (a -> m b) -> m [b]

第一个参数可以是[],这很容易。

meh [] _ = pure []

主案例应该执行 f 提供的操作,然后递归地meh执行列表的其余部分,并收集结果:

meh (x:xs) f = do
    r <- f x
    rs <- meh xs f
    pure (r:rs)

或不do加符号:

meh (x:xs) f =
    f x >>= \r -> meh xs f >>= \rs -> pure (r:rs)

或者Applicative说:

meh (x:xs) f = (:) <$> f x <*> meh xs f

推荐阅读