为什么嵌套在其他monad中的IO不能执行?有没有办法迫使他们去?

Lam*_*ist 4 monads haskell

这是我上一个问题的后续跟进. IO动作嵌套在未执行的其他monad中

该问题的解决方案是删除一些monad,并允许执行IO操作.

为什么我需要取消monad?有没有办法在没有取消的情况下执行IO?

注意:这是一个假设,而不是关于好的或坏的做法的问题.

hao*_*hao 10

也许这会有助于将其IO视为type IO a = World -> (a, World); 也就是说,一个函数将其唯一参数作为计算机的当前状态,并返回一个新状态和一些值a.这IO与GHC内部的实际实现并没有太大的不同,所以希望我们可以原谅这种类比的(卑鄙)交流方法.

所以readFile :: FilePath -> IO String,例如,成为readFile :: FilePath -> World -> (a, World).

而且main :: IO ()是真的main :: World -> ((), World).

然而,这意味着具有类型的值IO _是惰性的.它们只是功能!在给定值之前,函数不能执行任何操作; 在我们的例子中,函数想要的值是一个World对象,我们无法构造它.这就是Haskell中IO的美妙之处:我们可以IO通过使用我们熟悉和喜欢的monadic运算符(return,bind)来构建一个动作,但是在运行时传入World对象之前它不能做任何事情.

这意味着IO我们构建的任何未通过线程的操作main都不会被执行.

所以,有了foobar :: [Char] -> IO [IO ()],我们当然可以观察到返回值:

main :: IO ()
main = do
  ios <- foobar "string"
  print "goodbye"
Run Code Online (Sandbox Code Playgroud)

但是,直到我们解构ios并约束IO那些行动所接受的内在价值World:

main :: IO ()
main = do
  ios <- foobar
  ios !! 0
  ios !! 1
  ios !! 2
  ...
  print "goodbye"
Run Code Online (Sandbox Code Playgroud)

或者,简而言之,

main = do
  ios <- foobar
  sequence ios
  print "goodbye"
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.


dup*_*ode 5

让我们从一个稍微不同的例子开始。如您所知, aString是以下列表Char

GHCi> :set +t
GHCi> "Mississippi"
"Mississippi"
it :: [Char]
Run Code Online (Sandbox Code Playgroud)

的列表Strings是 的列表的列表Char;这是一个[[Char]]

GHCi> group "Mississippi"
["M","i","ss","i","ss","i","pp","i"]
it :: [[Char]]
Run Code Online (Sandbox Code Playgroud)

group "Mississippi"是 a [[Char]],我不希望将其作为 a 处理[Char]- 这会破坏使用的意义group

IO a对于大多数用途来说,值与任何其他值一样,因此也适用类似的考虑。为了给出一个具体的(和现实的)例子,假设我们有一个这种类型的函数......

(KeyCode -> IO ()) -> IO (IO ())
Run Code Online (Sandbox Code Playgroud)

...它在 GUI 中注册按键事件的事件处理程序。这个想法是,您使用参数调用该函数KeyCode -> IO (),该参数指定响应按键时应该发生的情况,并运行结果,IO (IO ())以便您选择的KeyCode -> IO ()处理程序变为活动状态。然而,该操作生成的内部函数 有不同的用途:它取消注册事件处理程序,并且您可以自行决定在应用程序的稍后位置使用它 - 也许永远不会。在这种情况下,您绝对不想在外部操作之后立即运行内部操作!IO () IO (IO ())

总而言之,一个IO (IO a)动作IO在运行时会产生另一个IO动作,您可能也想运行也可能不想运行。

PS:正如 sheyll在其他问答中提到的,join可用于展平嵌套IO操作或任何其他嵌套单子值。顺便说一句,列表也有一个Monad实例。你认为join (group "Mississippi")会做什么?