无盒类型,如Int#
和严格函数,如f (!x) = ...
,有些不同,但我看到概念上的相似性 - 它们以某种方式不允许thunk/laziness。如果Haskell是像Ocaml这样严格的语言,那么每个函数都将是严格的,每种类型都会被拆箱。拆箱类型和严格执行之间的关系是什么?拆箱类型和严格性之间的关系是什么?
回答
无盒装VS盒装数据
为了支持parametric polymorphism和laziness,默认情况下Haskell的数据类型被统一表示为一个指向closure上the heap,具有这样的结构:
这些是“盒装”值。一个拆箱对象由值本身直接表示,没有任何间接或闭包。 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'例子?它是否与懒惰的对象具有相同的表示形式? – haskelline 2012-07-03 08:15:03
它具有相同的表示形式,但语义不同。这样的结构通常是有用的。 – 2012-07-03 12:29:22
但我认为,例如'data Pair = P Int Int'将包含比'data Pair = P!Int!Int'更多的间接字符。在前者中,每个参数是指向一个指针(一个thunk)的指针,而在后者中它是一个指向值的指针? – haskelline 2012-07-03 13:25:57
拆箱类型必然是严格的,但并非所有严格的值都必须拆箱。
data Foo a = Foo !a !a
有两个严格的领域
data Bar a = Bar {-# UNPACK #-} !Int !a
有两个严格的领域,但第一个是拆箱。
最终,unboxed类型(必然)严格的原因是没有地方存储thunk,因为它们只是扁平的,在那一点上是哑数据。任何类型的
参数可以由“严格”,但具有相应boxed类型的唯一的装箱类型是Char#
,Int#
,Word#
,Double#
和Float#
。
如果您知道像C这样的低级语言,则更容易解释。无盒类型类似于int
,double
等,盒装类型与int*
,double*
等相同。当您有int
时,您已经知道整个值,因为它是以位模式表示的,因此它不是懒。它也必须严格,因为所有int
的值都是有效的,而不是⊥。
但是,给定int*
后,您可能会选择取消引用指针以获取实际值(因此为惰性),并且可能包含无效指针(它包含⊥,即非严格指针)。
- 1. C++和Ruby之间的关系和依赖关系是什么?
- 2. 可见性和排序之间的关系/区别是什么?
- 3. Hits中Elastic_score和NEST Score属性之间的关系是什么?
- 4. “严格”和“松散”行为之间的区别是什么?
- 5. 各种Android OpenGL相关类之间的关系是什么?
- 6. dup()和close()系统调用之间的关系是什么?
- 7. 什么是严格的时间表?
- 8. using关键字和IDisposable接口之间的关系是什么?
- 9. JLS,Java和相关技术之间的关系是什么?
- 10. JSDoc:模块和名称空间之间的关系是什么
- 11. 负载和响应时间之间的关系是什么?
- 12. 它是什么类型的关系?
- 13. (类型)值和类型(值)之间的区别是什么?
- 14. tsconfig.json和gulp.js之间有什么关系?
- 15. MariaDB和MySQL之间有什么关系?
- 16. '@ 1'和'@ 2'之间有什么关系
- 17. __getattr__和getattr之间有什么关系?
- 18. PyTorch和Torch之间有什么关系?
- 19. STL和stdlib之间有什么关系
- 20. IRimTable和PersistenceStore之间有什么关系?
- 21. seneca和redis之间有什么关系
- 22. MIDP和JME(和Android)之间的关系是什么?
- 23. uniform sampler2D和GL_TEXTURE [NUM]和glGenTexture之间的关系是什么?
- 24. 拆箱值类型
- 25. 什么是严格和非严格的模拟?
- 26. Windows Phone的XNA和XNA之间的关系是什么?
- 27. virtualenvwrapper中的环境和项目之间的关系是什么?
- 28. UIView的setNeedsLayout,layoutIfNeeded和layoutSubviews之间的关系是什么?
- 29. Model和Array之间的关系是什么?它的复杂
- 30. 什么是Lisp的向量和列表之间的关系?
我对拆箱类型没有太多经验,所以即使是基本的评论也是受欢迎的。 – sdcvvc 2010-06-28 10:22:59
由于多态性,并非所有类型都将被拆箱。 OCaml和Haskell中的多态函数使用值的统一表示法作为闭包。 Haskell允许专门化,生成使用非盒装参数的自定义函数(OCaml可能也会这样做)。 – 2010-06-28 16:36:14