未包装类型,例如 Int#, 和严格的功能, f (!x) = ..., ,有所不同,但我看到概念上的相似之处 - 它们在某种程度上不允许thunks/懒惰。如果Haskell是像OCAML这样的严格语言,则每个功能都将是严格的,并且每种类型都没有盒装。未包装类型与强制执行严格之间有什么关系?

有帮助吗?

解决方案

未盒子与盒装数据

支持 参数多态性懒惰, ,默认情况下,Haskell数据类型统一表示为指向 关闭, ,具有这样的结构:

alt text
(来源: haskell.org)

这些是“盒装”值。一个 拆箱 对象由值本身直接表示,而无需任何间接或闭合。 Int 被装箱,但是 Int# 被拆箱。

懒值 要求 盒装表示。严格的值不会:它们可以表示为堆上的完全评估的封闭,也可以表示为原始的未盒子结构。注意 指针标记 是我们可以在盒装对象上使用的优化,以在闭合指针中编码构造函数。

与严格关系的关系

通常,功能语言编译器以临时方式生成未盒的值。但是,在哈斯克尔 未框的值 很特别。他们:

  1. 他们有另一种, #;
  2. 只能在特殊的地方使用;和
  3. 它们是未装修的,因此并未表示为指向堆值的指针。

因为他们是无法置换的,所以他们一定是严格的。 不可能表示懒惰。

因此,特定的未箱类型,例如 Int#, Double#, ,实际上是在机器上(以c符号)为double或int表示的。

严格分析

分别是GHC确实 严格分析 常规Haskell类型。如果发现值的使用很严格 - 即永远不会“未定义” - 优化器可能会替换常规类型的所有用途(例如 Int)带有未包装的一个(Int#),因为它知道使用 Int 总是严格的,因此用更有效(且始终严格)的类型代替 Int# 是安全的。

当然,我们可以拥有严格的类型,而没有未盒的类型,例如,元素 - 图片多态性列表:

data List a = Empty | Cons !a (List a)

在其元素上是严格的,但并不表示它们为未框的值。

这也指出了您对严格语言的错误, 像Ocaml. 。他们仍然需要支持多态性,因此他们要么提供统一的表示,要么对每种类型的数据类型和功能进行专业化。 GHC默认情况下使用统一表示,OCAML也是如此,尽管GHC也可以 专业类型和功能 现在(例如C ++模板)。

其他提示

未包装的类型必然是严格的,但并非所有严格的值都必须取消框。

data Foo a = Foo !a !a

有两个严格的领域

data Bar a = Bar {-# UNPACK #-} !Int !a

有两个严格的字段,但第一个字段是未包装的。

最终,未盒装类型的原因(一定是严格)是没有地方存储thunk,因为它们只是平坦的,愚蠢的数据。

任何类型的参数都可以“严格”,但是唯一具有相应盒装类型的未框类型是 Char#, Int#, Word#, Double#Float#.

如果您知道像C这样的低级语言,则更容易解释。未包装类型就像 int, double, 等等,盒装类型就像 int*, double*, 等等。当你有一个 int, ,您已经知道以位模式表示的整体值,因此,它并不懒惰。这也必须严格,因为 int 是有效的,不是⊥。

但是,给定一个 int* 您可以选择以后再解释指针以获取实际值(因此懒惰),并且有可能具有无效的指针(其中包含⊥,即非图案)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top