我是否需要了解 Haskell 如何表示数据才能编写好的 Haskell 程序?
我正在从 Java 背景学习 Haskell。当我编写 Java 程序时,我觉得我对对象在内存中的布局及其后果有深入的了解。例如,我确切地知道 java.lang.String
和 java.util.LinkedList
是如何工作的,因此我知道应该如何使用它们。对于 Haskell,我有点迷失了。例如,(:)
是如何工作的?我应该关心吗?是否在某处指定?
I'm learning Haskell from a Java background. When I program Java, I feel like I have a strong understanding of how objects are laid out in memory and the consequences of this. For example I know exactly how java.lang.String
and java.util.LinkedList
work and therefore I know how I should use them. With Haskell I'm a bit lost. For example, how does (:)
work? Should I care? Is it specified somewhere?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
简短的回答是否定的。在 Haskell 中编程时,您应该将数据结构视为纯数学对象,而不用担心它们在内存中的表示方式。原因是,在没有副作用的情况下,除了创建数据的函数以及可用于提取构造数据的更简单部分的函数之外,实际上没有任何数据。 。
要查看有关
(:)
等数据构造函数或任何其他术语的信息,请使用:type
(或简称为:t
)命令GHCi 内部:这告诉您
(:)
构造函数(发音为“cons”)接受任何类型的值和相同类型的列表,并返回相同类型的列表。您还可以使用:info
命令获取更多信息。这将向您展示数据定义的样子:这告诉您
(:)
是将元素添加到现有列表的构造函数。我还强烈推荐 Hoogle 不仅可以按名称查找内容,还可以进行相反的搜索;您知道您正在寻找的函数的签名,并且想要查找是否有人已经为您编写了该函数。 Hoogle 很好,因为它提供了描述和示例用法。
归纳数据的形状
我上面说过,了解数据在内存中的表示并不重要...但是,您应该了解您正在处理的数据的形状,以避免糟糕的结果绩效决策。 Haskell 中的所有数据都是归纳定义的,这意味着它具有树状形状,不断向外递归展开。您可以通过查看数据的定义来判断数据的形状;一旦您知道如何阅读此内容,它的性能特征就真的没有什么隐藏的了:
正如您从定义中看到的,获得新的
MyList
的唯一方法是通过Cons
构造函数。如果你多次使用这个构造函数,你最终会得到大致如下形状的东西:它只是一棵没有分支的树,这就是列表的定义!获得
a1
的唯一方法是依次弹出每个Cons
;因此,访问最后一个元素的时间复杂度为O(n),而访问头部的时间复杂度为常数。一旦您可以根据数据结构的定义对数据结构进行此类推理,您就一切就绪了。The short answer is no. When programming in Haskell you should think of your data structures as pure mathematical objects and not worry about how they're represented in memory. The reason for this is that, in the absence of side-effects, there's really nothing to data except the functions that create it and the functions you can use to extract the simpler parts out of which it was constructed.
To see information about data constructors like
(:)
, or any other terms, use the:type
(or just:t
for short) command inside GHCi:That tells you that the
(:)
constructor (pronounced "cons"), takes a value of any type, and a list of the same type, and returns a list of the same type. You can also get a bit more info by using the:info
command. This will show you what the data definition looks like:This tells you that
(:)
is the constructor which prepends an element to an existing list.I also highly recommend Hoogle not only for looking up things by name but for doing the reverse kind of search; where you know the signature of the function you're looking for and want to find if someone's already written it for you. Hoogle is nice because it gives descriptions and example usages.
Shapes of Inductive Data
I said above that it's not important to know the representation of your data in memory... you should, however, understand the shape of the data you're dealing with, to avoid poor performance decisions. All data in Haskell is inductively defined, meaning it has a tree-like shape which unfolds ever outwards recursively. You can tell the shape of data by looking at its definition; there's really nothing hidden about its performance characteristics once you know how to read this:
As you can see from the definition, the only way you can get a new
MyList
is by theCons
constructor. If you use this constructor multiple times, you'll end up with something roughly of this shape:It's just a tree with no branches, that's the definition of a list! And the only way to get at
a1
is by popping off each of theCons
s in turn; hence access to the last element is O(n), whereas access to the head is constant time. Once you can do this kind of reasoning about data structures based on their definitions, you're all set.简短的回答是“不”,您不需要了解数据布局——但了解复杂性会很有用。
然而,要编写高度优化的 Haskell 程序,对堆中数据结构的形状有充分的了解是必不可少的。一个可以帮助实现此目的的工具是 "vacuum",它可以渲染 Haskell 数据结构的图表正如它们所布置的那样。
一些示例:
以下是有关如何使用该工具的简短视频:http:// /www.youtube.com/watch?v=X4-212uMgy8
Short answer is "no", you don't need to know about data layouts -- a knowledge of complexity will be useful though.
To write highly optimized Haskell programs, a good working knowledge of the shape of data structures in the heap is essential, however. A tool to help this is "vacuum", which can render diagrams of Haskell data structures as they are laid out.
Some examples:
Here's a short video of how to use the tool: http://www.youtube.com/watch?v=X4-212uMgy8