![](/img/trans.png)
[英]How to inject the result of an IO action into a non-IO monadic computation
[英]How can I use the result of an IO action in an non-IO-function?
这个 function 接受一个文件路径并返回文件的内容。 该文件包含一些相同长度的行。 ——曾经是一张原始图。
parsePicture :: FilePath -> IO()
parsePicture fileName = do
content <- lines <$> readFile fileName
print content
现在我尝试实现 function 来垂直翻转“图片”:
type Picture = [[Char]]
flipVertical :: IO() -> Picture
flipVertical xs = map reverse xs
但我只得到以下错误代码:
zuP12.hs:24:31: error:
• Couldn't match expected type ‘[[Char]]’ with actual type ‘IO ()’
• In the second argument of ‘map’, namely ‘xs’
In the expression: map reverse xs
In an equation for ‘flipVertical’: flipVertical xs = map reverse xs
|
24 | flipVertical xs = map reverse xs
| ^^
Failed, no modules loaded.
如何在 parsePicture 的结果上使用我的 function flipVertical?
这个 function... 返回文件的内容。
不,它没有。 它将文件的内容打印到 STDOUT。 在大多数情况下,您应该考虑放入 STDOUT 的信息已经消失——这些信息已经离开您的程序,现在位于终端屏幕上,或者用户选择放置它的任何其他地方,但程序无法再访问它。
(严格来说,可以将 STDOUT 重定向回您自己的程序,但这是一个很大的 hack,不要这样做。)
相反,您应该更改 function 以便它确实返回内容:
parsePicture :: FilePath -> IO Picture
parsePicture fileName = do
content <- lines <$> readFile fileName
return content
...或者干脆
parsePicture fileName = lines <$> readFile fileName
其行为完全相同(根据 monad 法则)。
另外,我宁愿称之为loadPicture
:解析不应该涉及文件读取。
当然,您仍然可以稍后打印内容,例如
main = do
...
fooPicture <- parsePicture "foofilename"
print fooPicture
...
至于flipVertical
,这不应该与IO
有任何关系。 它只是一个纯粹的 function
flipVertical :: Picture -> Picture
flipVertical xs = map reverse xs
可以像这样使用,例如
main = do
...
fooPicture <- parsePicture "foofilename"
print $ flipVertical fooPicture
...
或者
main = do
...
fooVFPicture <- flipVertical <$> parsePicture "foofilename"
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.