如何在Haskell中拼接单子列表?IO [[String]]与IO [String]拼接问题
解决Haskell中IO列表拼接的类型不匹配问题
先明确你的变量类型:
x :: IO [[String]]:IO上下文包裹的二维字符串列表y :: IO [String]:IO上下文包裹的一维字符串列表
你之前的写法错误在于直接把IO包裹的值当作普通列表操作——IO是monadic上下文,必须先提取内部的纯值,才能进行列表拼接,最后再把结果放回IO上下文里。
正确实现方式
方式1:使用do表达式(最直观)
combined :: IO [[String]] combined = do xList <- x -- 取出x内部的[[String]]纯值 yItem <- y -- 取出y内部的[String]纯值 return (xList ++ [yItem]) -- 将yItem作为单个元素追加到xList末尾,再包回IO
方式2:用>>=链式操作(不使用do notation)
combined = x >>= \xList -> y >>= \yItem -> return (xList ++ [yItem])
方式3:使用Applicative的liftA2(更简洁)
import Control.Applicative (liftA2) combined = liftA2 (\xList yItem -> xList ++ [yItem]) x y
为什么你的原有写法报错?
y >>= return . (++) [x]:[x]是[IO [[String]]]类型,而(++)要求两个普通列表([a] -> [a] -> [a]),IO包裹的值无法直接参与列表拼接,类型完全不匹配。y <> [x]:<>作为Monoid操作符,IO的Monoid逻辑是执行两个动作但返回后者结果,但[x]是列表类型,和y的IO [String]类型不兼容,自然触发类型错误。
核心逻辑就是:先从IO上下文里取出纯值完成列表操作,再把结果放回IO上下文。
内容的提问来源于stack exchange,提问作者tugudd
相关产品推荐
相关产品推荐

