Haskell 中“undefined”的类型签名意味着什么?

2024-01-10

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

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

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

错误的特殊情况。预计编译器将认识到这一点并插入更适合上下文的错误消息undefined出现。

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

Thanks!


这是@leftaroundabout 答案的延续。

在 Haskell 中,值有类型。但类型他们自己也有类型。当一种类型充当另一种类型的类型时,我们将其称为“种类”。

Haskell 中最重要和最常见的类型是Type http://hackage.haskell.org/package/base-4.12.0.0/docs/Data-Kind.html#t:Type,通常在签名中表示为*。它是一种“提升”的类型,也就是说,其值可以是 thunk,在求值时可以发散、抛出错误等......例如类型Int有善良Type.

还有其他类型,例如Int# http://hackage.haskell.org/package/ghc-prim-0.5.3/docs/GHC-Prim.html#g:3那是not举起。类型的值Int# is never一声重响,它始终是内存中的实际值。

简而言之,值在内存中的表示是受控按他们的类型。

RuntimeRep http://hackage.haskell.org/package/ghc-prim-0.5.3/docs/GHC-Types.html#t:RuntimeRep是另一种。它是这样的类型LiftedRep and IntRep。这些类型没有任何值,它们的存在只是为了在类型级别表达事物 https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html?highlight=datakinds#extension-DataKinds, 正如我们将看到。

有一种超神奇的类型级实体叫做TYPE http://hackage.haskell.org/package/ghc-prim-0.5.3/docs/GHC-Types.html#t:TYPE当用 kind 的类型参数化时RuntimeRep(即使用描述内存中表示的类型)返回其值具有该表示的类型。例如,Type is TYPE LiftedRep,而那种Int# is TYPE 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 in all函数,无论是返回 kind 类型的函数Type,还有返回 kind 类型的函数TYPE IntRep(换句话说:Int#type) 或返回另一个未提升类型的函数。否则,我们将需要多个不同版本的undefined,这会很烦人。

解决方案是使undefined 轻率多态性。签名表示:对于任何可能的内存中表示(RuntimeRep)并且对于任何可能的type其值具有该表示形式,undefined计算该类型的成员。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Haskell 中“undefined”的类型签名意味着什么? 的相关文章

随机推荐