为什么不能通过严格的评估来欺骗Haskell进行IO操作? [英] Why can't Haskell be tricked into performing IO operations by using strict evaluation?
问题描述
我正在学习Haskell和IO monad.我想知道为什么这不会迫使程序输出"hi"和"bye":
I'm just learning Haskell and IO monads. I'm wondering why wouldn't this force the program to output "hi" as well as "bye":
second a b = b
main = print ((second $! ((print "hi") >>= (\r -> return ()))) "bye")
据我了解, $!
运算符将强制对 second
的第一个参数求值,而>> =
运算符将需要运行 print"hi"
,以获取其值并将其传递给 \ r->return()
,它将在屏幕上显示"hi".
As far as I understand, the $!
operator would force the first argument of second
to be evaluated, and the >>=
operator would need to run print "hi"
in order to get a value off of it and pass it to \r -> return ()
, which would print "hi" to the screen.
我的推理出了什么问题?
What's wrong with my reasoning?
而且,有什么方法可以证明Haskell不能被欺骗(除了使用不安全的函数),使其在安全"代码中运行IO操作?
And also, is there any way to proove Haskell cannot be tricked (other than using unsafe functions) into running IO operations inside "safe" code?
推荐答案
您要强制使用的表达式是((print"hi")>> =(\ r-> return()))
,其类型为 IO()
.因此,它代表IO操作.但是评估这样的事情与运行它完全不同!
The expression you are forcing is ((print "hi") >>= (\r -> return ()))
, which is of type IO ()
. As such it represents an IO action. But evaluating such a thing is quite different from running it!
评估值意味着只需执行足够的步骤即可将其转化为所谓的弱头正常形态.由于 IO
是抽象的,因此在这种情况下了解其含义有些棘手,但是可以将 IO a
视为 RealWorld->.(a,RealWorld)
,那么弱头正常形式就是等待得到 RealWorld
的函数.
Evaluating a value means performing just enough steps to turn it into what is called weak head normal form. Because IO
is abstract, it is a bit tricky to see what that means in this case, but one can think of IO a
as RealWorld -> (a, RealWorld)
, and then the weak head normal form is, well, a function waiting to be given the RealWorld
.
运行暗示评估,但还会传递 RealWorld
作为参数,从而导致发生 IO
效果.
Running implies evaluation, but also passes the RealWorld
as an argument, thus causing the IO
effect to happen.
所有这些都不是专门针对 IO
的;您的困惑和概念同样适用于 a->b
.如果您了解第二个参数是函数时 $!
的作用,那么您将了解当它是IO操作时会发生什么.
All this is not very specific to IO
; your confusion and the concepts apply equally to a -> b
. If you understand what $!
does when the second argument is a function, you’ll understand what happens when it is an IO action.
这篇关于为什么不能通过严格的评估来欺骗Haskell进行IO操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!