Jua*_*uan 16 monads haskell io-monad
我只是在学习Haskell和IO monads.我想知道为什么这不会强制程序输出"hi"以及"bye":
second a b = b
main = print ((second $! ((print "hi") >>= (\r -> return ()))) "bye")
Run Code Online (Sandbox Code Playgroud)
据我所知,$!
运算符会强制要求第一个参数second
进行求值,并且>>=
运算符需要运行print "hi"
以便从中获取值并将其传递\r -> return ()
给屏幕,这将打印"hi"到屏幕.
我的推理有什么问题?
而且,有没有办法证明Haskell不能被欺骗(除了使用不安全的函数)在"安全"代码中运行IO操作?
Joa*_*ner 33
你强迫的表达式((print "hi") >>= (\r -> return ()))
是类型IO ()
.因此,它代表IO动作.但是评估这样的事情与运行它是完全不同的!
评估一个值意味着执行足够的步骤将其转换为所谓的弱头正常形式.因为IO
是抽象的,在这种情况下看到这意味着什么有点棘手,但是人们可以认为IO a
是RealWorld -> (a, RealWorld)
,然后弱头正常形式是一个等待给予的函数RealWorld
.
运行意味着评估,但也传递RealWorld
作为参数,从而导致IO
效果发生.
所有这些都不是非常具体的IO
; 你的困惑和概念同样适用于a -> b
.如果你理解$!
当第二个参数是一个函数时会发生什么,你就会明白当它是一个IO动作时会发生什么.
dfe*_*uer 21
你对评估和执行感到困惑.当您强制使用表达式时print "hi"
,不会打印任何内容.它只生成一个值(在这种情况下,类型的值IO()
),表示打印出来的操作.您可以将print "hi"
作为打印"hi"的配方的价值想象出来.