问题标签 [discriminated-union]

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 投票
4 回答
2991 浏览

f# - F# 联合成员的 Enum.GetName 等效项是什么?

我想获得Enum.GetNameF# 歧视工会成员的等价物。调用ToString()给了我 TypeName+MemberName,这不是我想要的。当然,我可以对它进行子串化,但它安全吗?或者也许有更好的方法?

0 投票
3 回答
1434 浏览

f# - 歧视联盟&让绑定?

为什么在有区别的联合中不允许使用 let 绑定?我认为这与在默认构造函数中执行的 let 绑定有关吗?

在第二点上,任何关于我如何重写的建议AI_Choose都将不胜感激。我想将加权优先级与 AI 保持在一个元组中。我的想法是AI_Weighted_Priority继承AI_Priority和覆盖选择。我不想处理不同长度的压缩列表(糟糕的做法 imo。)

0 投票
2 回答
233 浏览

f# - F# 中表达式的最佳表示

我正在开发一个从 LINQ 表达式(基本上是 LINQ-to-SQL 的修改子集)生成 SQL 的库。我正在使用有区别的联合来建模 SQL 表达式,但遇到了一些(感知的?)限制。我想做类似以下的事情(注意最后一行):

我可以执行以下操作:

...并将最后两行更改为:

但这似乎有两个问题:

  1. SqlOrderByExpression 不是 SqlExpression。这使得很难使用访问者模式(也许这就是问题所在?)。这意味着在遍历 Select 表达式时,我无法通过将每个表达式传递给 Visit(expr:SqlExpression) 的表达式来迭代顺序列表。

  2. SqlOrderByExpression 仅仅是一个元组的类型别名,所以没有类型信息被保留。这会损害 IMO 的可读性。

有没有更好的方法来建模这个?我尝试了继承路线,但我认为 DU 更容易使用(除非有提到的困难)。

0 投票
4 回答
711 浏览

arrays - 从 F# 中不同类型数组的可区分联合中获取类型化数组

如果我有不同类型数组的区分联合,我如何将它们转换为它们的“实际”类型?

当我得到 foo 的值时运行上述内容后,我看到:

如何从 foo 获取实际的 int 数组?我只是错过了一些允许我访问类似内容的语法 foo.[2]吗?我无法通过 foo 枚举,所以我无法使用 map。我可以为 ItemStuff 编写一个成员,它为我返回的每种不同类型的数组返回一个正确类型的数组,但这似乎不正确?

我在这里最好的方法是什么?

这就是我最终要做的。关于更好的方法的任何想法?

0 投票
2 回答
457 浏览

f# - 升级 FParsec:升级有区别的联合以满足新的平等/比较约束

因此,通过一系列有趣的事件,我下载了FParsec源代码并尝试构建它。不幸的是,它与新的 1.9.9.9 不兼容。我解决了简单的问题,但是有几个受歧视的工会仍然不起作用。

具体来说,Don Syme 的帖子解释了包含类型项的可区分联合obj->不会自动获得相等或比较约束,因为对象不支持比较并且函数也不支持相等。(不清楚自动生成的相等/比较之前是否有问题,但现在它们不再生成,代码甚至无法编译。)

以下是有问题的 DU 的一些示例:

以下是违规用途:

或者,对于比较约束

据我所知,Don 用唯一的 int 标记每个实例的解决方案是实现自定义相等/比较约束的正确方法(或者可能是唯一的 int 元组,以便可以对 DU 的各个分支进行排序)。但这对于DU的用户来说是不方便的。现在,DU 的构建需要调用一个函数来获取下一个标记。

有没有办法隐藏标签获取并向库的用户提供相同的构造函数?也就是在不改变接口的情况下改变实现?这一点尤其重要,因为它看起来(根据我对代码的理解)PrecedenceParserOp是一种公共类型。

0 投票
1 回答
983 浏览

.net - Haskell 在 F# 中的“衍生秀”?

deriving Show在 Haskell 中,通过简单地添加到类型定义中,很容易使代数类型/可区分联合“可显示”为字符串。

在 F# 中,我最终会编写如下内容:

显然,更复杂的类型会变得更糟。

deriving Show有什么方法可以在 F#中获得类似的东西?

0 投票
6 回答
3627 浏览

c# - 如何在 C# 中复制 F# 可区分联合类型?

我创建了一个名为 Actor 的新类,它处理传递给它的消息。我遇到的问题是弄清楚将相关但不同的消息传递给 Actor 的最优雅方式是什么。我的第一个想法是使用继承,但它看起来很臃肿,但它是强类型,这是一个明确的要求。

有什么想法吗?

例子

演员类

0 投票
2 回答
383 浏览

f# - 如何在有区别的联合中使用符号/标点符号

我正在尝试为自然语言解析器返回的词性标签和其他标签创建一个有区别的联合。

在 C#/Java 中通常使用字符串或枚举来表示它们,但在 F# 中区分联合似乎更合适,因为它们是不同的只读值。

在语言参考中,我发现这个符号 ``...`` 可以用来分隔关键字/保留词。这适用于

type ArgumentType =
| A0 // subject
| A1 // indirect object
| A2 // direct object
| A3 //
| A4 //
| A5 //
| AA //
| ``AM-ADV``

但是,标签包含像 $ 这样的符号,例如

type PosTag =
| CC // Coordinating conjunction
| CD // Cardinal Number
| DT // Determiner
| EX // Existential there
| FW // Foreign Word
| IN // Preposision or subordinating conjunction
| JJ // Adjective
| JJR // Adjective, comparative
| JJS // Adjective, superlative
| LS // List Item Marker
| MD // Modal
| NN // Noun, singular or mass
| NNP // Proper Noun, singular
| NNPS // Proper Noun, plural
| NNS // Noun, plural
| PDT // Predeterminer
| POS // Possessive Ending
| PRP // Personal Pronoun
| PRP$ //$ Possessive Pronoun
| RB // Adverb
| RBR // Adverb, comparative
| RBS // Adverb, superlative
| RP // Particle
| SYM // Symbol
| TO // to
| UH // Interjection
| VB // Verb, base form
| VBD // Verb, past tense
| VBG // Verb, gerund or persent participle
| VBN // Verb, past participle
| VBP // Verb, non-3rd person singular present
| VBZ // Verb, 3rd person singular present
| WDT // Wh-determiner
| WP // Wh-pronoun
| WP$ //$ Possessive wh-pronoun
| WRB // Wh-adverb
| ``#``
| ``$``
| ``''``
| ``(``
| ``)``
| ``,``
| ``.``
| ``:``
| `` //not sure how to escape/delimit this

``...`` 不适用于 WP$ 或 (

另外,我有一个有趣的问题,解析器返回 `` 作为一个有意义的符号,所以我也需要转义它。

有没有其他方法可以做到这一点,或者这是不可能的歧视工会?

现在我遇到了类似的错误

  • 无效的命名空间、模块、类型或联合案例名称
  • 可区分的联合案例和异常标签必须是大写标识符

我想我可以以某种方式覆盖这些愚蠢的情况下的 toString 并用一些等效的字母数字替换符号?

0 投票
15 回答
56952 浏览

c# - C#中的可区分联合

[注意:这个问题的原标题是“ C# 中的 C (ish) style union ”,但正如 Jeff 的评论告诉我的,显然这个结构被称为“discriminated union”]

原谅这个问题的冗长。

在 SO 中已经有几个类似的问题需要挖掘,但它们似乎专注于联合的内存节省优势或将其用于互操作。 这是一个这样的问题的例子

我想要一个联合类型的东西有点不同。

我现在正在编写一些代码,它生成看起来有点像这样的对象

相当复杂的东西我想你会同意的。问题是它ValueA只能是几种特定类型(比如说stringintFoo(这是一个类),并且ValueB可以是另一小组类型。我不喜欢将这些值视为对象(我想要温暖舒适的感觉带有一点类型安全性的编码)。

所以我想写一个简单的小包装类来表达 ValueA 在逻辑上是对特定类型的引用这一事实。我打电话给这门课Union是因为我想要达到的目标让我想起了 C 中的联合概念。

使用这个类 ValueWrapper 现在看起来像这样

这与我想要实现的目标相似,但我缺少一个相当关键的元素 - 即在调用 Is 和 As 函数时编译器强制类型检查,如下代码所示

IMO 询问 ValueA 是否是 a 是无效的,char因为它的定义清楚地表明它不是 - 这是一个编程错误,我希望编译器能够解决这个问题。[另外,如果我能做到这一点,那么(希望)我也会得到智能感知——这将是一个福音。]

为了实现这一点,我想告诉编译器类型T可以是 A、B 或 C 之一

有谁知道我想要实现的目标是否可行?还是我一开始就写这门课是愚蠢的?

提前致谢。

0 投票
4 回答
1195 浏览

f# - F# 歧视联合中的共享案例

我想写这样的东西:

编译器抱怨NumExpExpin之间的冲突getValue。即使以下失败:

有没有办法在与函数一起工作的两个有区别的联合中使用相同的情况?DU 定义本身是可以的。

我想使用相同的情况来避免添加间接级别,例如

Exp定义中。我觉得我在这里遗漏了一些非常基本的东西。

我拥有的原因NumExp是我希望能够将 2 '插入' Expa Dot(而不是 2 个浮点数),因为它使生成表达式更容易,但它们不能是 any Exp,只是数字。

编辑:我真正想知道的是两个 DU 中的两个案例是否可以被视为同一个实体(有点像Exp“包括” NumExp)。我现在意识到Exp.Num并且NumExp.Num是完全独立的实体。Tomas 提供了一种区分以下两种情况的好方法。