未装箱类型和严格性之间有啥关系?
Posted
技术标签:
【中文标题】未装箱类型和严格性之间有啥关系?【英文标题】:What is the relationship between unboxed types and strictness?未装箱类型和严格性之间有什么关系? 【发布时间】:2011-03-09 01:48:53 【问题描述】:未装箱的类型,如Int#
,和严格的函数,如f (!x) = ...
,有些不同,但我看到概念上的相似性——它们在某种程度上不允许thunk/laziness。如果 Haskell 是像 Ocaml 这样的严格语言,那么每个函数都是严格的,并且每个类型都没有装箱。未装箱类型与执行严格性之间有什么关系?
【问题讨论】:
我对未装箱类型没有太多经验,所以即使是基本的评论也欢迎。 由于多态性,并非所有类型都会被拆箱。 OCaml 和 Haskell 中的多态函数使用值的统一表示作为闭包。 Haskell 允许专业化,生成使用未装箱参数的自定义函数(OCaml 可能也这样做)。 【参考方案1】:未装箱与装箱数据
为了支持parametric polymorphism 和laziness,默认情况下,Haskell 数据类型统一表示为指向the heap 上的closure 的指针,其结构如下:
(来源:haskell.org)
这些是“装箱”值。 unboxed 对象直接由值本身表示,没有任何间接或闭包。 Int
已装箱,但 Int#
未装箱。
惰性值需要盒装表示。严格值不会:它们可以表示为堆上完全评估的闭包,也可以表示为原始的未装箱结构。请注意,pointer tagging 是一种优化,我们可以在装箱对象上使用,以在指向闭包的指针中编码构造函数。
与严格的关系
通常,未装箱的值由函数式语言编译器以特别的方式生成。然而,在 Haskell 中,unboxed values 是特殊的。他们:
-
他们有不同的类型,
#
;
只能在特殊的地方使用;和
它们未提升,因此不表示为指向堆值的指针。
因为他们没有被提升,所以他们必然是严格的。懒惰的表现是不可能的。
因此,特定的未装箱类型,如 Int#
、Double#
,在机器上实际上被表示为 double 或 int(用 C 表示法)。
严格性分析
另外,GHC 执行常规 Haskell 类型的 strictness analysis。如果发现一个值的使用是严格的——即它永远不会是“未定义的”——优化器可能会用一个未装箱的(Int#
)替换所有常规类型的使用(例如Int
),因为它知道使用Int
总是严格的,因此用更有效(并且总是严格)的类型Int#
替换是安全的。
我们当然可以有没有未装箱类型的严格类型,例如,一个元素严格的多态列表:
data List a = Empty | Cons !a (List a)
在其元素中是严格的,但不将它们表示为未装箱的值。
这也指出了您在严格语言方面所犯的错误,like OCaml。它们仍然需要支持多态性,因此它们要么提供统一的表示,要么将数据类型和函数专门用于每种类型。 GHC 默认使用统一表示,OCaml 也是如此,尽管 GHC 现在也可以specialize types and functions(如 C++ 模板)。
【讨论】:
那么有没有使用严格的盒装类型,比如你的List
例子?它不是和它的惰性对应物具有相同的表示吗?
表示相同,但语义不同。这种结构通常很有用。
但我认为,例如,data Pair = P Int Int
将包含比data Pair = P !Int !Int
更多的间接寻址。在前者中,每个参数是否都是指向指针(thunk)的指针,而在后者中,它是指向值的指针?【参考方案2】:
未装箱的类型一定是严格的,但并非所有严格的值都一定是未装箱的。
data Foo a = Foo !a !a
有两个严格字段
data Bar a = Bar -# UNPACK #- !Int !a
有两个严格字段,但第一个未装箱。
归根结底,未装箱类型(必然)严格的原因是没有地方存储 thunk,因为那时它们只是扁平的、愚蠢的数据。
【讨论】:
【参考方案3】:任何类型的参数都可以设置为“严格”,但只有Char#
、Int#
、Word#
、Double#
和Float#
。
如果您了解 C 等低级语言,则更容易解释。未装箱的类型如int
、double
等,装箱的类型如int*
、double*
等。当你有int
时,你已经知道它所代表的整个值因此,在位模式中,它不是懒惰的。它也必须严格,因为 int
的所有值都是有效的,而不是 ⊥。
但是,给定int*
,您可以选择稍后取消引用指针以获取实际值(因此是惰性的),并且可能有无效的指针(它包含⊥,即非严格)。
【讨论】:
以上是关于未装箱类型和严格性之间有啥关系?的主要内容,如果未能解决你的问题,请参考以下文章
UIPageViewController 和 UIPageControl 之间有啥关系?