首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法将类型‘[]’与预期的‘IO’匹配:IO (IO ())实际:[IO ()]

无法将类型‘[]’与预期的‘IO’匹配:IO (IO ())实际:[IO ()]
EN

Stack Overflow用户
提问于 2021-07-11 17:27:34
回答 1查看 290关注 0票数 0

我是哈斯克尔的新手。

代码语言:javascript
复制
showAllContent file = do 
  content <- readFile file
  let splittedContent = splitOn "\n" content
  [beautyPrint x | x <- splittedContent]

beautyPrint line = do
    putStrLn line

我想在打印前转换字符串,但是我得到了错误

无法将类型"[]“与预期的" IO”匹配: IO (IO ()实际:IO ()

)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-11 17:34:01

看看这部分错误

Expected: IO (IO ()) Actual: [IO ()]

它告诉您,您已经将IO ()类型的东西包装到一个列表中,从而获得了一个[IO ()],而不是一个IO,这将导致所需的IO (IO ())

毕竟,当您执行[beautyPrint x | x <- splittedContent]时,您将从splittedContent中“提取”内容,并在其上执行beautyPring,但随后您将其包装在一个带有[]的列表中,而不是在IO monad中。

现在使用return,您可以在IO monad中包装一件东西,但是您有不止一件事情(这就是为什么要使用列表理解),您有一个列表,每个东西都来自相应的beautyPrint x

那么,你怎么能把它们都包装在一个IO中呢?sequence来帮助我们。看看它的签名:

代码语言:javascript
复制
sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)

对于IO Monad和list ([]) Traversable的具体情况,

代码语言:javascript
复制
sequence :: [IO ()] -> IO [()]

所以你可以

代码语言:javascript
复制
sequence [beautyPrint x | x <- splittedContent]

然后,由于您知道您正在对列表中的每个元素执行beautyPrint,所以您可以轻松地将其重写为

代码语言:javascript
复制
sequence $ map beautyPrint [x | x <- splittedContent]

然后删除(现在)冗余列表理解:

代码语言:javascript
复制
sequence $ map beautyPrint splittedContent

如果您正确地设置了IDE,那么IDE应该可以帮助您看到可以进一步简化它:

代码语言:javascript
复制
mapM_ beautyPrint splittedContent
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68338522

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档