【问题标题】:What are lifted and unlifted product types in Haskell?Haskell 中提升和未提升的产品类型是什么?
【发布时间】:2016-10-12 05:04:09
【问题描述】:

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

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

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

在这种情况下,术语“已提升”和“未提升”是什么意思?

【问题讨论】:

标签: haskell types


【解决方案1】:

来自GHC docs

“提升”类型意味着该类型的术语可能是底部。

“盒装”类型意味着一个值由指向堆对象的指针表示。

一些影响包括:

  • 提升的类型被装箱(但不一定是其他方式 - 查看上面的链接了解更多信息)
  • 未装箱的类型不能有 thunk(因为它们是指向数据的指针,告诉您如何产生值),所以不要懒惰。他们真的只是持有价值观。这也意味着它们可以更快。
  • 多态性不适用于未提升的类型。每当您看到一个类型变量时,所涉及的所有类型都会被取消。像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 中并且是原始类型。有一些讨论允许将自定义未提升数据类型集成到 GHC here

最后一句话:提升类型有种类*,未提升类型有种类#This answer 对 cme​​ts 中链接的问题进行了更详细的说明。

【讨论】:

  • “多态性不适用于未提升的类型”:bzzzt。 unboxed 类型不能使用多态性。多态性适用于未提升的类型,例如在 ML 中(尽管 Haskell 的种类系统可能不够灵活,无法支持它)。
  • @jcast 确实如此 - 我的意思是在 Haskell 的种类系统上下文中的注释,其中类型变量具有种类 *,除非另有说明。下面的链接实际上显示了如何使用 GHC 8.0 的更新的 levity 多态性功能来解除此限制。这说明清楚了吗?
  • 多态可以通过使用种类多态来处理未提升的类型:forall (k :: RuntimeRep) (t :: TYPE k) :)
【解决方案2】:

来自 GHC documentation

Lifted

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

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

同时,未提升的类型没有那些潜在的麻烦的额外值。这在纯粹的“语义”级别中很有用(如果您不想要那些额外的值),它还可以通过减少代价高昂的间接调用来促进更有效的实现。名为the worker-wrapper transformation 的 GHC 优化利用了这一点(请参阅链接论文的第 5.1 节)。

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

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

【讨论】:

    猜你喜欢
    • 2011-01-24
    • 1970-01-01
    • 1970-01-01
    • 2013-07-31
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    • 1970-01-01
    • 2012-11-02
    相关资源
    最近更新 更多