我是哈斯克尔的新手。
showAllContent file = do
content <- readFile file
let splittedContent = splitOn "\n" content
[beautyPrint x | x <- splittedContent]
beautyPrint line = do
putStrLn line我想在打印前转换字符串,但是我得到了错误
无法将类型"[]“与预期的" IO”匹配: IO (IO ()实际:IO ()
)
发布于 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来帮助我们。看看它的签名:
sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)对于IO Monad和list ([]) Traversable的具体情况,
sequence :: [IO ()] -> IO [()]所以你可以
sequence [beautyPrint x | x <- splittedContent]然后,由于您知道您正在对列表中的每个元素执行beautyPrint,所以您可以轻松地将其重写为
sequence $ map beautyPrint [x | x <- splittedContent]然后删除(现在)冗余列表理解:
sequence $ map beautyPrint splittedContent如果您正确地设置了IDE,那么IDE应该可以帮助您看到可以进一步简化它:
mapM_ beautyPrint splittedContenthttps://stackoverflow.com/questions/68338522
复制相似问题