我只是在学习Haskell和IO monad。我想知道为什么这不会强制程序输出"hi“和”再见“:
second a b = b
main = print ((second $! ((print "hi") >>= (\r -> return ()))) "bye")
据我所知,$!
操作符将强制计算second
的第一个参数,而>>=
操作符需要运行print "hi"
才能从中获取值并将其传递给\r -> return ()
,后者将在屏幕上显示"hi“。
我的推理有什么问题?
此外,有没有办法防止Haskell不会被欺骗(除了使用不安全的函数)在“安全”代码中运行IO操作?
发布于 2014-07-16 16:25:41
您强制使用的表达式是IO ()
类型的((print "hi") >>= (\r -> return ()))
。因此,它表示IO操作。但是评估这样的东西和运行它是完全不同的!
评估一个值意味着执行足够的步骤将其转换为所谓的weak head normal form。因为IO
是抽象的,所以要理解它在本例中的含义有点棘手,但可以将IO a
想象成RealWorld -> (a, RealWorld)
,然后弱头部范式是一个等待RealWorld
的函数。
运行意味着计算,但也会将RealWorld
作为参数传递,从而导致IO
效应的发生。
所有这些都不是IO
所特有的;您的困惑和概念同样适用于a -> b
。如果您理解了当第二个参数是函数时$!
做了什么,那么就会理解当它是一个IO操作时会发生什么。
发布于 2014-07-16 16:26:29
你混淆了评估和执行。当您强制使用像print "hi"
这样的表达式时,不会输出任何内容。它只生成一个值(在本例中,是一个IO()
类型的值),表示打印输出的操作。您可以将print "hi"
的值看作是打印"hi“的秘诀。
https://stackoverflow.com/questions/24775528
复制相似问题