问题标签 [algebraic-data-types]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
8 回答
16457 浏览

data-structures - Haskell 的代数数据类型

我试图完全理解 Haskell 的所有概念。

代数数据类型在哪些方面类似于泛型类型,例如,在 C# 和 Java 中?它们有什么不同?他们到底有什么代数?

我熟悉通用代数及其环和域,但我对 Haskell 的类型如何工作只有一个模糊的概念。

0 投票
8 回答
660 浏览

c# - 请确认或更正我对此 Haskell 代码片段的“英文解释”

我是一名 C# 开发人员,正在通过“Real World Haskell”工作以真正理解函数式编程,因此当我学习 F# 时,我会真正了解它,而不仅仅是“用 F# 编写 C# 代码”,可以这么说.

好吧,今天我遇到了一个例子,我以为我理解了 3 次不同的时间,然后才看到我错过的东西,更新我的解释,然后递归(相信我,还有诅咒)。

现在我相信我确实明白了,我在下面写了详细的“英文解释”。您能否请Haskell大师确认理解,或指出我错过了什么?

注意:Haskell 代码片段(直接从书中引用)定义了一个自定义类型,该类型与内置的 Haskell 列表类型同构。

Haskell 代码片段

编辑:经过一些回复,我看到了我犯的一个误解,但对纠正该错误的 Haskell“解析”规则不太清楚。所以我在下面包含了我原来的(不正确的)解释,然后是更正,然后是我仍然不清楚的问题。

编辑:这是我对片段的原始(不正确)“英文解释”

  1. 我正在定义一种名为“List”的类型。
  2. List 类型是参数化的。它有一个类型参数。
  3. 有 2 个值构造函数可用于创建 List 的实例。一个值构造函数称为“Nil”,另一个值构造函数称为“Cons”。
  4. 如果您使用“Nil”值构造函数,则没有字段。
  5. “Cons”值构造函数有一个类型参数。
  6. 如果您使用“Cons”值构造函数,则必须提供 2 个字段。第一个必填字段是 List 的一个实例。第二个必填字段是 a 的实例。
  7. (我故意省略了关于“定义表演”的任何内容,因为它不是我现在想要关注的一部分)。

更正后的解释如下(以粗体表示的变化)

  1. 我正在定义一种名为“List”的类型。
  2. List 类型是参数化的。它有一个类型参数。
  3. 有 2 个值构造函数可用于创建 List 的实例。一个值构造函数称为“Nil”,另一个值构造函数称为“Cons”。
  4. 如果您使用“Nil”值构造函数,则没有字段。

    5.(此行已被删除......它不准确)“Cons”值构造函数具有单个类型参数。

  5. 如果您使用“Cons”值构造函数,则必须提供 2 个字段。第一个必填字段是 a 的实例。第二个必填字段是“List-of-a”的一个实例。

  6. (我故意省略了关于“定义表演”的任何内容,因为它不是我现在想要关注的一部分)。

仍然不清楚的问题

最初的困惑是关于片段中“Cons a (List a)”的部分。事实上,这是我仍然不清楚的部分。

人们已经指出,“Cons”标记之后的行上的每个项目都是一个类型,而不是一个值。所以这意味着这一行说“Cons 值构造函数有 2 个字段:一个是 'a' 类型,另一个是 'list-of-a' 类型。”

知道这一点很有帮助。但是,仍有一些不清楚的地方。当我使用 Cons 值构造函数创建实例时,这些实例将第一个“a”“解释”为“将传入的值放在此处”。但他们不会以同样的方式解释第二个“a”。

例如,考虑这个 GHCI 会话:

当我键入“Cons 0 Nil”时,它使用“Cons”值构造函数来创建 List 的实例。从 0 开始,它得知类型参数是“Integer”。到目前为止,没有混淆。

但是,它确定了 Cons 的第一个字段的值为 0。但它不确定第二字段的……它仅确定第二个字段的类型为“List Integer”。

所以我的问题是,为什么第一个字段中的“a”表示“这个字段的类型是'a' 这个字段的值是'a'”,而第二个字段中的“a”表示“类型这个字段是'List of a'”?

编辑:我相信我现在已经看到了曙光,这要归功于一些回应。让我在这里表达一下。(如果以某种方式仍然不正确,请务必让我知道!)

在片段“Cons a (List a)”中,我们说“Cons”值构造函数有两个字段,第一个字段的类型为“a”,第二个字段的类型为“List of a” '。

这就是我们所说的!特别是,我们对价值观只字未提!这是我错过的一个关键点。

稍后,我们要创建一个实例,使用“Cons”值构造函数。我们在解释器中输入:“Cons 0 Nil”。这明确地告诉 Cons 值构造函数使用 0 作为第一个字段的值,并使用 Nil 作为第二个字段的值。

这就是它的全部。一旦您知道 value 构造函数定义只指定types,一切都会变得清晰。

感谢大家的有用回复。正如我所说,如果还有什么问题,请务必告诉我。谢谢。

0 投票
4 回答
1007 浏览

data-structures - 在 Haskell 代数数据类型中选择备选方案

当类型X定义为:

我想要Int一个X值,如果有的话,否则为零。

如何确定X参数的类型returnInt是什么?

0 投票
1 回答
404 浏览

xml - 在 XML XSD 中定义递归代数数据类型

想象一下,我有一个像这样的递归代数数据类型(Haskell 语法):

我想用 XML 来表示它,并且我想要一个 XSD 模式。

我已经想出了如何实现这种语法:

使用此架构:

但我真正想要的是这种语法:

这可能吗?

谢谢!

0 投票
5 回答
3990 浏览

haskell - 代数类型数据构造函数的“模式匹配”

让我们考虑一个具有许多构造函数的数据类型:

我想编写一个函数来检查是否使用相同的构造函数生成了两个值:

维护sameK不是很有趣,不能轻易检查其正确性。例如,当向 中添加新的构造函数时T,很容易忘记更新sameK。我省略了一行来举例:

问题是如何避免样板sameK?或者如何确保它检查所有T构造函数?


我发现的解决方法是为每个构造函数使用单独的数据类型,派生Data.Typeable和声明一个公共类型类,但我不喜欢这个解决方案,因为它的可读性要差得多,否则只是一个简单的代数类型对我有用:

0 投票
2 回答
1612 浏览

scala - F# 和 Scala 中的 ADT

F# 和 Scala 中的 ADT 之间的主要区别是什么?有什么 F# 的 ADT 可以做但 Scala 的 ADT 不能(反之亦然)的事情吗?

0 投票
2 回答
8209 浏览

haskell - Haskell 数据类型的内存占用

如何找到在 Haskell(主要是 GHC)中存储某种数据类型的值所需的实际内存量?是否可以在运行时评估它(例如在 GHCi 中),或者是否可以从其组件估计复合数据类型的内存需求?

一般来说,如果类型a和内存需求b已知,那么代数数据类型的内存开销是多少,例如:

例如,这些值在内存中占用了多少字节?

我知道由于垃圾收集延迟,实际内存分配更高。由于惰性评估,它可能会有很大的不同(并且 thunk 大小与值的大小无关)。问题是,给定一个数据类型,它的值在完全评估时需要多少内存?

我发现 GHCi 中有一个:set +s选项可以查看内存统计信息,但不清楚如何估计单个值的内存占用量。

0 投票
3 回答
1667 浏览

functional-programming - 除了幺半群之外,函数式编程中是否使用了任何代数结构?

我最近开始了解函数式编程(在 Haskell 和 Scala 中)。它的功能和优雅非常迷人。

但是当我遇到使用名为 Monoid 的代数结构的 Monads 时,我很惊讶也很高兴看到我从数学中学到的理论知识被用于编程。

这个观察让我想到了一个问题:群、域或环(其他请参见代数结构)可以在编程中用于更多抽象和代码重用目的并实现类似数学的编程吗?

据我所知,名为Fortress的语言(一旦编译器完成,我肯定会更喜欢任何语言)在其库代码中定义了这些结构。但到目前为止我看到的唯一用途是我们已经熟悉的数字类型。它们还有其他用途吗?

最好的问候, ciun

0 投票
1 回答
158 浏览

silverlight - F# / SIlverlight 绑定到代数数据类型

给定一个数据结构:

以及希望能够显示任一候选人的数据网格,是否可以绑定(使用 WPF 绑定)到 ScorableCandidate?

我不这么认为,因为绑定语法需要能够解构类型——我认为这是不可能的。

谢谢

0 投票
4 回答
1161 浏览

haskell - 是否可以在 GHCi 中定义新的 ADT

在评论 ghci 中的新功能时,我希望 ghci 能够声明类型声明和声明新的 ADT 类型,有人告知这确实是可能的,在搜索后我发现 这个页面告诉我我可以做到

显然,同样的语法适用于模式匹配(例如,让 a 1=True;a 2=False)。

创建 ADT 会使其几乎完美吗?有谁知道目前是否可行?我应该只制作一个 ADT 暂存文件并重新加载它吗?

PS 有谁知道有没有这样做的计划?是否有 ghc(i) 的功能要求?

我也知道它的开源,但我目前还不够聪明,无法破解 ghc(i)。