我正在帮助朋友学习Haskell,他最近创建了类似这样的代码,该类型在运行时检查并生成CPU烧录循环。我完全被这个困惑了。为什么导入Control.Applicative允许这个错误的代码类型检查?
import Control.Monad
import Control.Applicative
main = forever putStrLn "Hello, infinity"
这不应该键入检查,但是。正确的版本显然是:
main = forever $ putStrLn "Hello, infinity"
有什么奇怪,令我感到诧异的是,你有和没有进口Control.Applicative不同的结果。不导入它,它不类型检查:
Prelude Control.Monad> forever putStrLn "Hello, infinity"
<interactive>:1:1:
No instance for (Monad ((->) String))
arising from a use of `forever'
Possible fix: add an instance declaration for (Monad ((->) String))
In the expression: forever putStrLn "Hello, infinity"
In an equation for `it': it = forever putStrLn "Hello, infinity"
我没有看到一个((->) String
单子实例在源Control.Applicative,所以我猜奇怪的事情正在发生,由于其使用的Control.Category或Control.Arrow,但我不知道。所以我想我有两个问题:
- 什么是导入Control.Applicative,让这种情况发生?
- 进入无限循环时发生了什么?在这种情况下,Haskell实际上试图执行什么?
感谢,
您能否详细说明'( - >)e'的实例对于什么有用? – 2012-03-17 20:37:55
@DanielLyons当您有许多功能都需要访问某些共享的配置信息时,它非常有用。然后你可以写(例如)'foo >> = bar >> = baz',而不是像'\ e - > let x = foo e; y = bar x e; z = baz y e in y'。 – 2012-03-17 21:08:50