Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 返回IO操作的后果是什么?_Haskell_Io_Monads_Io Monad - Fatal编程技术网

Haskell 返回IO操作的后果是什么?

Haskell 返回IO操作的后果是什么?,haskell,io,monads,io-monad,Haskell,Io,Monads,Io Monad,在Haskell中,类型构造函数IO是一个monad,它配备了return语句,可以将任何表达式提升到其IO版本 并没有什么能阻止我们将已经是IO操作的内容提升到它的IO版本-给我们一种形式IO(ioa) 例如,我可以编写以下程序: main = return . print $ "Hello world" 一经执行,什么也不做 我的问题是,当执行此主程序时,引擎盖下会发生什么 在任何情况下,返回IO操作是否有意义?IO通常近似于状态现实世界,即在“真实世界”上运行的状态单子returnfor

在Haskell中,类型构造函数
IO
是一个monad,它配备了
return
语句,可以将任何表达式提升到其
IO
版本

并没有什么能阻止我们将已经是
IO
操作的内容提升到它的
IO
版本-给我们一种形式
IO(ioa)

例如,我可以编写以下程序:

main = return . print $ "Hello world"
一经执行,什么也不做

我的问题是,当执行此主程序时,引擎盖下会发生什么


在任何情况下,返回IO操作是否有意义?

IO
通常近似于
状态现实世界,即在“真实世界”上运行的
状态
单子
return
for
State
生成一个不会改变包含状态的操作。因此,打个比方,
返回
将任何内容发送到
IO
也不会做任何事情。不仅当您
返回
某些
IO a
时,而且当您返回任何
a

返回一个
IO
操作可用于在一个地方建立一个计算(沿途将一些值捕获到一个闭包中)并在其他地方执行它。很像在C中传递回调

实际上,要建立一个
IO
计算并将其传递到其他地方,您可以在do块内使用
let

main :: IO ()
main = do
  let act = readFile "somefile" -- action is not performed yet
  foo act -- pass the action as a parameter

foo :: IO () -> IO ()
foo act = do
  .. do something
  result <- act -- actually perform the action
  ..

在这里,我们需要一个
filename
来创建我们的操作,但是
getLine
也在
IO
中。这就是额外级别的
IO
出现的地方。当然,这个示例是合成的,因为您可以在引擎盖下执行
filename,运行时会有效地丢弃
IO
action
main
的结果,这就是为什么它通常被定义为
IO()
。这意味着如果
main
实际上有一个类似
IO(IO Int)
的类型,那么就没有真正的问题。执行
IO
操作,结果(另一个
IO
操作)被丢弃,未执行


在程序的更深处,更可能触发类型错误。例如,
fmap doSomething(return.getLine)
不会进行类型检查,如果您的意思是
fmap doSomething getLine

小挑剔:这是一个
IO(IO a)
@Zeta谢谢!现在修正了,你能不能加一个你在最后一段中谈到的例子?@jsevilamol更新了我的答案。
main :: IO ()
main = do
  act <- do
    filename <- getLine
    return (readFile filename)
  foo act