我最近遇到了“起重产品类型”一词,与未起重的产品形成对比。

我记不清上下文,但是我看到Stack Overflow上还有其他问题,询问未提起产品类型(example)的缺点。

我或多或少知道什么是产品类型。它类似于(a, b)Foo a b c,大致对应于集合论中的笛卡尔积。

在这种情况下,“提起”和“未提起”是什么意思?

最佳答案

GHC docs:

“提升”类型表示该类型的术语可能在最底端。

“盒装”类型表示值由指向堆对象的指针表示。

一些影响包括:

  • 将提升类型装箱(但不一定是其他方法-请查看上面的链接以获取更多信息)
  • 未装箱的类型不能有重击(因为这些是指向数据的指针,告诉您如何产生该值),因此不会出现延迟。他们真的只是持有价值观。这也意味着它们可以更快。
  • 多态不适用于未提升的类型。每当您看到类型变量时,所有涉及的类型都会被取消。像id 0 :: Int#这样的东西不起作用。请查看this answer,以了解如何(自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中找到唯一未提升的类型,并且它们是原始类型。进行了一些讨论,以允许将 undefined 的自定义数据类型集成到GHC here中。

    最后一点:提升类型的类型为*,未提升类型的类型为#。注释中链接的问题的This answer对此有更详细的说明。

    09-28 14:00
    查看更多