问题标签 [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 投票
1 回答
1036 浏览

c++ - 如何在 C++ 中实现无参数仿函数及其返回值的可区分联合?

我知道我可以使用boost::variant并避免不得不问这个问题。但是使用boost::variant涉及到很多丑陋的代码。尤其是游客很乱。所以,事不宜迟……

我编写了以下模板类来实现对柯里化函数的惰性求值。(有关整个片段,请参阅我之前的问题。)

所以我想更新它以包括记忆。从概念上讲,它非常简单。首先,我必须更换:

和:

但是还剩下两件事。首先,我必须更新operator _Ret,如果它执行惰性求值,那么结果实际上会被记忆。其次,我必须添加一个析构函数,以便根据 的值_evaluated,要么 要么_fun_res销毁。这是我不太确定如何做事的地方。

_fun首先,这是替换为的正确方法_res吗?如果没有,我该怎么做?

其次,这是选择性破坏的正确方法_fun还是_res?如果没有,我该怎么做?

0 投票
5 回答
1206 浏览

f# - 作为可区分联合的特定成员的列表元素的计数

Let's say I have a discriminated union:

Then, I want to check how many members of a list are of type Baz:

Is there a more idiomatic way to do this?

0 投票
1 回答
688 浏览

reflection - 映射有区别的联合中的所有值

假设我有一个受歧视的工会:

以及将可区分联合映射到某个值的函数:

我想生成一个包含工会每个成员的成本的地图,例如:

这可能吗?我希望能够做类似的事情:

这个问题很有帮助,但不是我所需要的;我希望能够访问内存中的工会成员,而不仅仅是检查他们的属性。

我想这样做的原因是我可以有一个可区分的联合代表游戏中所有不同类型的牌,以及一个告诉你每张牌在开始时应该有多少张的函数,然后轻松生成初始卡片到计数的映射。有一个更好的方法吗?

0 投票
7 回答
4281 浏览

types - 在 Clojure 中表示 sum 类型(ab)的惯用方式

已编辑。我现在的问题是:在静态类型语言中,通常使用什么惯用的 Clojure 构造而不是 sum 类型?到目前为止的共识:如果行为可以统一,则使用协议,否则使用标记对/映射,在前置和后置条件中放置必要的断言。

Clojure 提供了多种表示产品类型的方法:向量、映射、记录……,但是如何表示总和类型,也称为标记联合和变体记录?类似于Either a bHaskell 或Either[+A, +B]Scala 中的东西。

我想到的第一件事是带有特殊标签的地图:{:tag :left :value a},但是所有代码都将被条件污染,(:tag value)如果不存在则处理特殊情况......我想确保的是那:tag总是存在的,它只能采用一个指定的值,并且对应的值始终具有相同的类型/行为并且不能是nil,并且有一种简单的方法可以看到我处理了代码中的所有情况。

我可以在 的行中想到一个宏defrecord,但对于 sum 类型:

这样的事情是否已经存在?回答:没有)。

0 投票
3 回答
566 浏览

properties - 如何将 setter 添加到 F# 中的可区分联合

我想将 setter 属性添加到有区别的工会,我应该怎么做?

费:

0 投票
1 回答
1380 浏览

f# - 有区别的工会结构/习惯平等

我有以下受歧视的工会:

card -> bool在我添加to之前,它具有结构上的平等性Spy这个问题对于如何对记录进行自定义相等很有帮助。但是,我不确定在这种情况下如何最好地实施它。我宁愿不必列举每个案例ActCard

这里有什么更好的方法?

0 投票
1 回答
198 浏览

generics - 如何在 F# 中使用通用计量单位指定联合子句?

无论如何定义一个DU,其条款使用通用计量单位?例如

此代码无法编译,但我可以指定一个常规函数,该函数接受具有通用度量单位的数值:

考虑到每个联合子句最终都是一个函数,它将之后指定的类型转换of为私有类型MyDU.A,或者MyDU.B是否有特定原因为什么它适用于函数定义而不是类型定义?

有没有办法在这里做我想做的事?如果没有,我很想知道为什么它也不起作用!

谢谢,

0 投票
2 回答
1303 浏览

f# - 为什么 None 表示为 null?

CompilationRepresentationFlags.UseNullAsTrueValue可以用来

允许使用 null 作为可区分联合中的 null 鉴别器的表示形式

Option.None是这方面最突出的例子。

为什么这很有用?与检查联合案例(生成的Tag属性)的传统机制相比,空检查如何更好?

它可能会导致意想不到的行为:

编辑

我测试了 Jack 的断言,即与 null 而不是静态只读字段相比更快。

使用 ILSpy,我可以看到t编译为 null(如预期的那样):

考试:

结果:

真实:00:00:00.036,CPU:00:00:00.046,GC gen0:0,gen1:0,gen2:0

如果该CompilationRepresentation属性被删除,t则成为静态只读字段:

结果是一样的:

真实:00:00:00.036,CPU:00:00:00.031,GC gen0:0,gen1:0,gen2:0

模式匹配t == null按照前一种情况和t is Z后一种情况进行编译。

0 投票
2 回答
2240 浏览

f# - F# 中单一大小写区分联合的简明模式匹配

假设我有以下单一案例歧视工会:

在某些时候我需要实际的字符串。我发现提取它的方法是:

有没有更简洁的方法来做到这一点?

我知道我的使用是一种特殊情况,匹配是有意义的,以确保您已经涵盖了可能性,只是想知道是否有办法做类似的事情:

0 投票
2 回答
512 浏览

f# - 如何折叠有歧视的工会

我正在尝试对受歧视的工会实施折叠。DU 称为 Expr,表示程序表达式,通常是递归的。我正在尝试编写一个折叠,以递归方式累积对 Expr 的操作结果。下面是我写折叠的尝试。

问题是代码不起作用,这是众所周知的,因为我在最后一行得到了the construct causes code to be less generic than indicated by the type annotations. The type variable 's has been constrained to be type 'Expr list'错误listFolded。这是因为 的定义foldProceduralExpr几乎肯定是错误的。

现在,我很想修复代码并因此修复类型错误,但我根本不知道如何。我想我缺乏的是对非列表或递归数据结构的折叠如何工作的理解。我最近将一个 trie 的折叠从 OCaml 翻译成 F#,并且在理解该折叠如何工作时遇到了很多麻烦。

问题 1:此代码是否有我可以理解的可见修复?

问题 2:是否有资源来获得理解如何编写这些类型的折叠所需的背景?

如果您需要更多信息,请告诉我。我没有将 DU 包括在内,因为它太大且太复杂,无法清楚地说明问题。希望可以说,这是典型的 Lisp 风格的 AST 数据结构。

后续问题:一旦它起作用,我也想用那个折叠写一张地图。这看起来像一张典型的地图,还是需要一些额外的脑力才能弄清楚?

编辑:关于 Tomas 的帮助,我已将最后三行变成 -

我希望这仍然有意义。

编辑:这是我的最终解决方案。它概括了得到孩子 -

我将 Expr 和 Expr 列表作为折叠值的原因是我想保留父/子关系的结构以供以后使用。这是一个非常特定于领域的折叠,在某种程度上我想。