未装箱类型和严格性之间有啥关系?

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 等低级语言,则更容易解释。未装箱的类型如intdouble 等,装箱的类型如int*double* 等。当你有int 时,你已经知道它所代表的整个值因此,在位模式中,它不是懒惰的。它也必须严格,因为 int 的所有值都是有效的,而不是 ⊥。

但是,给定int*,您可以选择稍后取消引用指针以获取实际值(因此是惰性的),并且可能有无效的指针(它包含⊥,即非严格)。

【讨论】:

以上是关于未装箱类型和严格性之间有啥关系?的主要内容,如果未能解决你的问题,请参考以下文章

销售领料登记单与装箱单之间接关系

共同的墙壁和旁边的房间之间有啥样的关系?

UIPageViewController 和 UIPageControl 之间有啥关系?

maskToBounds 和cornerRadius 之间有啥关系?

自动解除引用和解除引用强制之间有啥关系?

DBMS和文件处理系统之间有啥关系吗?