问题标签 [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.
scala - 类型类子类化
我想限制联合类型A
和B
类型的参数,其中B
一些通用类型将被子类型化。我想把对象放在这个方法中:
这是,我如何指定隐式:
现在,我可以放入 accept ,但Foo(5)
不能放在那里,编译器尖叫:。我在哪里可以指定子类型关系?Baz("a")
Bar
error: could not find implicit value for parameter ev: FooOrBaish[Baz]
f# - 为 F# 中的可区分联合自动生成谓词和访问器
是否可以在 F# 中以类型安全的方式为任意代数数据类型自动生成谓词和访问器?
例如,如果我们有用户定义的类型:
应该生成这样的东西:
如果可以为访问器指定名称可能带有这样的注释会更好:
如果我想简化对内部数据的访问,可能无法完成,或者我应该使用记录而不是区分联合(DU)。但是使用 DU 的模式匹配更简单,我希望同时获得这两个好处 - 简单的模式匹配和简单的“直接数据访问”。
f# - 从 F# DU 访问特定案例
假设我有以下 DU:
现在我在这样的函数中使用它:
这行得通,但我必须解构 DU 才能将其传递给 DoSomethingWith* 函数。尝试将 DoSomethingWithA 定义为:
但编译器抱怨没有定义类型 A。
想要将参数限制为Something.A,而不仅仅是任何旧的int,这似乎完全符合F#的哲学,所以我只是走错了路吗?
scala - F# 的可区分联合与 Scala 的案例类有何不同?还是一样?
我在网上四处寻找在 scala 中可能类似于或像 F# 可区分联合一样工作的东西,但无论我在哪里看,我都找不到任何东西,除了看起来有点像它的案例类。 . 但是它们到底有什么不同呢?
例如:
上面的代码基本上是一个案例类,还是我必须做一些不同的事情才能获得相同的功能?
f# - 如果受歧视的工会有很多选择,有什么问题吗?
是的,一个微不足道的问题,但我找不到专家意见。
我正在使用计算表达式对服务器端进程进行排序。当我的函数具有相同的签名时,它对我有很大帮助,因此我有一个区分联合,其中定义了不同的组合。我有几个快速的初学者问题。
DU 可以拥有的选项数量是否有推荐的上限?目前我的 DU 有九个选项,但这个数字会随着项目的进展而增加。如果我在项目结束时达到 30 或 40 怎么办?
如果某些选项变得“长”,可能会有问题吗?目前,平均期权有大约四五种基本类型——类似——
bool * string * XElement * int * string
但最长的一种具有以下定义:bool * int * int * int * string * XElement * XElement * DateTime 选项 * DateTime 选项 * string * Dictionary * Dictionary
我不希望有很多选择会在这么长的时间内出现。但是,我是否正在为性能方面的痛苦世界做好准备?
提前致谢。
f# - 如何在 f# 中为可区分联合定义运算符
我有代码来实现基元之间的一些几何运算
编译器说,运算符的模式匹配并不详尽,尽管这只是一个警告。如何在没有编译器抱怨的情况下仅在 DU 的特定子类型之间正确实现运算符?
f# - 何时在 F# 中使用区分联合与记录类型
在继续讨论复杂示例之前,我试图弄清 F# 的基础知识。我正在学习的材料介绍了区分联合和记录类型。我已经审查了两者的材料,但我仍然不清楚为什么我们会使用其中一种。
我创建的大多数玩具示例似乎都可以在两者中实现。记录似乎非常接近我认为的 C# 中的对象,但我试图避免依赖映射到 c# 作为理解 F# 的一种方式
所以...
是否有明确的理由使用其中一种?
是否存在某些适用的典型案例?
是否有某些功能在其中一个可用,而另一个则没有?
f# - F# 中可区分联合的类型扩展
我定义了以下有区别的联合:
然后我创建了一个漂亮的打印功能,如下所示:
现在我想让我的Expr
类型使用这个函数作为它的ToString()
方法。例如:
但我不能这样做,因为stringify
还没有定义。答案是定义Stringify
为 的成员Expr
,但我不想用这种会随着时间不断增长的特殊方法污染我的初始类型声明。因此,我决定使用一种抽象方法,我可以在文件中进一步使用内部类型扩展来实现该方法。这是我所做的:
但我收到以下编译器错误:
错误 FS0912: 扩充中不允许此声明元素
该消息甚至看起来都不正确(我还没有创建类型扩充),但我理解它为什么抱怨。它不希望我在有区别的联合类型上创建抽象成员,因为它不能被继承。尽管我真的不想要继承,但我希望它表现得像 C# 中的部分类,我可以在其他地方完成对它的定义(在本例中是同一个文件)。
我最终通过使用StructuredFormatDisplay
属性的后期绑定能力以及以下内容“作弊” sprintf
:
虽然现在sprintf
和两者都输出相同的字符串,但如果我想要的话ToString
,没有办法获得Add (Con 2,Con 3)
输出。(2 + 3)
那么还有其他方法可以做我想做的事情吗?
PS我还注意到,如果我将StructuredFormatDisplay
属性放在扩充而不是原始类型上,它就不起作用。这种行为对我来说似乎不正确。似乎 F# 编译器应该将属性添加到类型定义中,或者不允许类型扩充上的属性。
f# - v3.1中命名联合字段的编译形式
首先,F# 3.1 规范是否可以在线获得?如果是这样,这个问题的答案应该很容易找到。
我想知道带有命名字段的可区分联合的编译形式(在 3.1 中添加)是否将包含带有字段名称的属性,而不是通常的Item1
, Item2
, ... 属性。
f# - 如何检查与 FsUnit 的歧视性工会的情况?
我想检查一个值是否属于受歧视联合的特定情况,而不必检查任何包含的数据。我的动机是每个单元测试只测试一件事。
一个例子如下(最后两行给出编译错误):
这可以在 FsUnit 中完成吗?
我知道这个答案,但不想为每种情况编写匹配函数(在我的真实代码中,有两个以上)。