haskell - 在 Haskell 中评估\_ -> undefined

标签 haskell

我一直在读这个http://www.haskell.org/haskellwiki/Hask .我在这部分苦苦挣扎..

undef1 = undefined :: a -> b
undef2 =  \_ -> undefined

为什么他们会有这样的行为..
seq undef1 () = undefined
seq undef2 () = ()
undef2 () = undefined

这是什么原因?我想了解这种行为,但我什至不知道从哪里开始。特别是,为什么 undef2 在严格评估下表现不同?

最佳答案

特殊功能seq将其第一个参数评估为弱头范式,然后返回其第二个参数。可以找到关于 WHNF 的一个很好的解释 here ,但出于此答案的目的,我将只使用 Haskell wiki definition :

An expression is in weak head normal form (WHNF) if it's either:

  • a constructor (eventually applied to arguments) like True, Just (square 42) or (:) 1
  • a function applied to too few arguments (perhaps none) like (+) 2 or sqrt.
  • or a lambda abstraction \x -> expression.


重要的一点是,当表达式是构造函数时,seq只查看构造函数的标签。因此,seq (Just undefined) 1计算结果为 1 .

还有一点很重要,Haskell 中的所有类型都是 lifted - 也就是说,评估类型的值可能导致执行无限循环或抛出异常(通常使用 errorundefined )。在我们评估了 seq a b 之后,我们可以确定评估 a到 WHNF 不会导致无限循环或异常。

有了这些知识,让我们看一下您的示例:
undef1 = undefined :: a -> b
undef2 =  \_ -> undefined

seq undef1 ()被评估,seq首先尝试找出以上三个类别中的哪一个 undef1属于。但是undef1undefined ,因此整个表达式的计算结果为 undefined .

但是,对于 seq undef2 () = () ,第一个参数是一个 lambda 抽象。由于seq看不到 lambda,它返回第二个参数。

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

关于haskell - 在 Haskell 中评估\_ -> undefined,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16041177/

相关文章:

haskell - IO值转换为Haskell函数

haskell - Rich Hickey 不使用自动柯里化(Currying) Clojure 函数的原因是什么?

模式匹配中的 Haskell (n+1)

performance - 加速 Haskell 中的分区计算

c++ - 如何在 C++ 中保留未定义的声明函数,如 Haskell 中的 `undefined`?

haskell - 为什么为否定参数定义 `take` 和 `drop`?

haskell - 强制 `stack` 重建已安装的软件包

haskell - 使用 Data.Comp.Unification 在 Haskell 中找到最通用的统一器(初学者问题)

haskell - 还记得 xmonad 工作区布局吗?

haskell - MT 堆栈中电梯的组成