Haskell中的升降类型是什么?

15

我最近接触到了“提升的积类型(lifted product type)”这个术语,与未提升的积类型相对比。

我记不清上下文了,但我看到Stack Overflow上有其他问题询问未提升积类型的缺点(例子).

我知道什么是积类型。像 (a, b) 或者 Foo a b c 这样的内容大致对应于集合论中的笛卡尔积。

在这个上下文中,“提升的”和“未提升的”这些术语是什么意思呢?


相关问题:https://dev59.com/HV4d5IYBdhLWcg3wLf4g - danidiaz
2个回答

12
GHC文档 中可以得知:
“提升的”类型意味着该类型的项可能是底部。
“装箱的”类型意味着一个值由指向堆对象的指针表示。
一些含义包括:
提升的类型是装箱的(但不一定相反 - 查看上面的链接以获取更多信息)
非装箱类型不能有thunks(因为它们是指向数据的指针,告诉您如何生成值),因此没有惰性。它们只是保存值。这也意味着它们可以更快。
多态与未提升类型无关。每当您看到一个类型变量时,所涉及的所有类型都是未提升的。像id 0 :: Int#这样的东西行不通。查看此答案,了解您可以在某些情况下(自GHC 8.0起)如何操纵它们。
请注意,您可以使用MagicHashUnboxedTuples扩展在GHC中创建未提升的产品(尽管我认为它们与GHCi不兼容):
{-# LANGUAGE MagicHash, UnboxedTuples #-}

extGCD :: Int -> Int -> (# Int, Int, Int #)
extGCD a 0 = (# 1, 0, a #)
extGCD a b = let (q, r) = a `quotRem` b
                 (# s, t, g #) = extGCD b r
             in  (# t, s - q * t, abs g #)

除了这个扩展,我相信你只会在GHC.Exts中找到未解除的类型,并且这些类型是原始类型。有一些讨论允许自定义的未解除数据类型被整合到GHC中这里
最后一个提醒:虽然提升的类型具有*类型,但未解除的类型具有#类型。这个问题的答案在评论中提供更多关于此的详细信息。

1
"多态性不适用于未装箱类型": bzzzt. 多态性不适用于未装箱类型。多态性与未提升的类型一起使用非常好,例如在ML中(尽管Haskell的种类系统可能不够灵活以支持它)。" - Jonathan Cast
@jcast 确实如此 - 我的意思是在 Haskell 的种类系统中,类型变量具有 * 种类,除非另有规定。随后的链接实际上展示了如何使用 GHC 8.0 的新等级多态特性解除这种限制。这样澄清了吗? - Alec
多态性可以与非提升类型一起使用,如果您想要这样做,可以使用种类多态性:forall (k :: RuntimeRep) (t :: TYPE k) :) - Poscat

10

来自 GHC 文档

Lifted

A type is lifted iff it has bottom as an element.

一个被提升类型的值可以是bottom。也就是说,它可以是undefined,或者可能是永远不会完成的计算,或者是抛出异常的计算。

与此同时,未被提升的类型没有这些潜在麻烦的额外值。这在纯粹的“语义”层面上可能有用(如果您不想要这些额外值),并且通过减少昂贵的间接引用,还可以促进更有效的实现。 GHC 优化称为worker-wrapper 转换利用了这一点(请参见链接论文的第5.1节)。

提升和未提升的类型具有不同的种类。提升的类型位于*中,未提升的类型位于#中。

目前,GHC 不允许您轻松定义自己的复杂未提升数据类型。但是,有提案允许这样做。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接