繁体   English   中英

“未定义”的类型签名在Haskell中意味着什么?

[英]What does type signature for `undefined` mean in Haskell?

我是Haskell的初学者,我对undefined函数的类型签名感到吃惊。

我期待更简单的东西,但我在Hackage上发现了这个:

undefined :: forall (r :: RuntimeRep). forall (a :: TYPE r). HasCallStack => a

一个特殊的错误案例。 预计编译器将识别这一点并插入更适合于出现undefined的上下文的错误消息。

你能解释一下这个签名是什么意思吗?

谢谢!

对于初学者需要知道的所有问题,签名很简单

undefined :: a

这意味着,与通常使用类型变量(即任何小写字母)一样, a普遍量化的 ,也可以是明确的:

{-# LANGUAGE ExplicitForall #-}
undefined :: forall a. a

......或者,我喜欢写它

{-# LANGUAGE ExplicitForall, UnicodeSyntax #-}
undefined :: ∀ a. a

量化被认为是所有类型的 ,即所有类型的东西* (读:“类型”,更准确的类型提升类型 - 提升意味着它可以是懒惰的thunk)。 因此,无论何种类型需要,您都可以在任何表达式中使用undefined

现在, undefined当然是一个“部分函数”之类的东西,基本上是一个无处定义的零参数的函数。 (FTR,它不是一个函数,因为定义函数参数[s]。)
您希望在实际评估时获得有用的错误消息,但GHC默认情况下不会为所有内容生成调用堆栈(出于性能原因),因此过去的情况是错误消息几乎完全无用。 这就是HasCallStack用武之地:这是一个约束,它实质上告诉了某些代码可能会发生undefined的上下文,它应该注意它发生的位置,以便错误消息实际显示出来。 所以,

undefined :: ∀ a. HasCallStack => a

这是一个有点令人困惑的是, HasCallStack后出现∀ a -这并不真的有什么关系a但在这背景下undefined将被使用。 只是,签名的形式总是如此

 :: .  => 

HasCallStack是一个约束,这就是它出现在中间的原因。 (更常见的情况是,约束实际上适用于您量化的其中一个类型变量。)

最后,这个RunTimeRep东西是关于levity多态的 我自己并不是真的了解它,但是在将未使用的类型与未装箱的类型一起使用时为什么未定义的函数是levity-polymorphic?

这是@ leftaroundabout答案的延续。

在Haskell中,值具有类型。 但类型本身也有类型。 当一个类型作为另一种类型的类型时,我们将其称为“种类”。

Haskell中最重要和最常见的类型是Type ,通常在签名中表示为* 它是那种“被提升”的类型,也就是说,它的值可以是thonks,当被评估时,可以发散,抛出错误等等......例如Int类型有Type

还有其他类型,如Int#没有解除。 Int#类型的值永远不是thunk,它始终是内存中的实际值。

总之,值的内存中表示由它们的类型的种类控制的

RuntimeRep是另一种。 它是LiftedRepIntRep等类型。 这些类型没有任何值,它们仅仅是为了在类型级别表达事物 ,我们将会看到。

有一个名为TYPE的超级魔法类型级实体,当使用类型RuntimeRep (具有描述内存中表示的类型)进行参数化时,返回其值具有该表示的类型。 例如, TypeTYPE LiftedRep ,而Int#TYPE IntRepTYPE IntRep

ghci> :set -XMagicHash
ghci> import GHC.Prim 
ghci> import GHC.Types
ghci> import Data.Kind
ghci> :kind (Int :: TYPE 'LiftedRep)
(Int :: TYPE 'LiftedRep) :: *
ghci> :kind Int#
Int# :: TYPE 'IntRep

现在我们可以回到为什么undefined有这么奇怪的签名。 问题是,我们希望能够在所有函数中使用undefined ,无论是返回类型Type函数,还是返回TYPE IntRep (换句话说: Int#类型)或返回的函数另一种未提升的类型。 否则,我们需要多个不同版本的undefined ,这会很烦人。

解决方案是使undefined levity-polymorphic 签名表示:对于任何可能的内存中表示( RuntimeRep )以及其值具有该表示的任何可能类型undefined计算该类型的成员。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM