我一直在阅读http://www.haskell.org/haskellwiki/Hask.我正在努力解决这个问题..
undef1 = undefined :: a -> b
undef2 = \_ -> undefined
Run Code Online (Sandbox Code Playgroud)
为什么他们这样做..
seq undef1 () = undefined
seq undef2 () = ()
undef2 () = undefined
Run Code Online (Sandbox Code Playgroud)
这是什么原因?我想了解这种行为,但我甚至不知道从哪里开始.特别是,为什么undef2在严格评估下表现不同?
特殊函数将seq其第一个参数计算为弱头正规形式,然后返回其第二个参数.可以在这里找到WHNF的一个很好的解释,但是为了这个答案的目的,我将使用Haskell维基定义:
表达式是弱头正常形式(WHNF),如果它是:
- 一个构造函数(最终应用于参数),如True,Just(square 42)或(:) 1
- 一个函数应用于太少的参数(可能没有),如(+)2或sqrt.
- 或lambda抽象\ x - >表达式.
重要的一点是,当表达式是构造函数时,seq只查看构造函数的标记.因此,seq (Just undefined) 1评估为1.
另一个重点是Haskell中的所有类型都被提升 - 也就是说,评估类型的值可能导致执行无限循环或抛出异常(通常使用error或undefined).在我们进行评估之后seq a b,我们可以确定a对WHNF的评估不会导致无限循环或异常.
有了这些知识,让我们来看看你的例子:
undef1 = undefined :: a -> b
undef2 = \_ -> undefined
Run Code Online (Sandbox Code Playgroud)
在seq undef1 ()评估时,seq首先尝试找出上述三个类别中的哪一个undef1属于.但undef1是undefined,所以整个表达式undefined.
但是,在这种情况下seq undef2 () = (),第一个参数是lambda抽象.由于seq无法看到lambda,它返回第二个参数.
第三个例子,undef2 () = undefined只是评估应用程序的直接结果(\_ -> undefined) ().
| 归档时间: |
|
| 查看次数: |
966 次 |
| 最近记录: |