我最近接触到了“提升的积类型(lifted product type)”这个术语,与未提升的积类型相对比。
我记不清上下文了,但我看到Stack Overflow上有其他问题询问未提升积类型的缺点(例子).
我知道什么是积类型。像 (a, b)
或者 Foo a b c
这样的内容大致对应于集合论中的笛卡尔积。
在这个上下文中,“提升的”和“未提升的”这些术语是什么意思呢?
id 0 :: Int#
这样的东西行不通。查看此答案,了解您可以在某些情况下(自GHC 8.0起)如何操纵它们。MagicHash
和UnboxedTuples
扩展在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中这里。*
类型,但未解除的类型具有#
类型。这个问题的答案在评论中提供更多关于此的详细信息。*
种类,除非另有规定。随后的链接实际上展示了如何使用 GHC 8.0 的新等级多态特性解除这种限制。这样澄清了吗? - Alecforall (k :: RuntimeRep) (t :: TYPE k)
:) - Poscat来自 GHC 文档:
Lifted
A type is lifted iff it has bottom as an element.
一个被提升类型的值可以是bottom。也就是说,它可以是undefined
,或者可能是永远不会完成的计算,或者是抛出异常的计算。
与此同时,未被提升的类型没有这些潜在麻烦的额外值。这在纯粹的“语义”层面上可能有用(如果您不想要这些额外值),并且通过减少昂贵的间接引用,还可以促进更有效的实现。 GHC 优化称为worker-wrapper 转换利用了这一点(请参见链接论文的第5.1节)。
提升和未提升的类型具有不同的种类。提升的类型位于*
中,未提升的类型位于#
中。
目前,GHC 不允许您轻松定义自己的复杂未提升数据类型。但是,有提案允许这样做。