在Haskell中评估\ _ - > undefined

use*_*154 7 haskell

我一直在阅读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在严格评估下表现不同?

Mik*_*kov 9

特殊函数将seq其第一个参数计算为弱头正规形式,然后返回其第二个参数.可以在这里找到WHNF的一个很好的解释,但是为了这个答案的目的,我将使用Haskell维基定义:

表达式是弱头正常形式(WHNF),如果它是:

  • 一个构造函数(最终应用于参数),如True,Just(square 42)或(:) 1
  • 一个函数应用于太少的参数(可能没有),如(+)2或sqrt.
  • 或lambda抽象\ x - >表达式.

重要的一点是,当表达式是构造函数时,seq只查看构造函数的标记.因此,seq (Just undefined) 1评估为1.

另一个重点是Haskell中的所有类型都被提升 - 也就是说,评估类型的值可能导致执行无限循环或抛出异常(通常使用errorundefined).在我们进行评估之后seq a b,我们可以确定a对WHNF的评估不会导致无限循环或异常.

有了这些知识,让我们来看看你的例子:

undef1 = undefined :: a -> b
undef2 =  \_ -> undefined
Run Code Online (Sandbox Code Playgroud)

seq undef1 ()评估时,seq首先尝试找出上述三个类别中的哪一个undef1属于.但undef1undefined,所以整个表达式undefined.

但是,在这种情况下seq undef2 () = (),第一个参数是lambda抽象.由于seq无法看到lambda,它返回第二个参数.

第三个例子,undef2 () = undefined只是评估应用程序的直接结果(\_ -> undefined) ().