scala - 返回类型密封时的凸性检查
问题描述
Scala 可以在密封类型上的模式匹配不详尽时发出警告,但是我们可以检查一个函数在返回类型是密封的情况下是否返回所有情况?例如,考虑以下 ADT
sealed trait Foo
case object Bar extends Foo
case object Qux extends Foo
然后f: Foo => String
对代数数据类型起作用Foo
def f(x: Foo): String = x match {
case Bar => "bar"
}
发出警告
match may not be exhaustive.
It would fail on the following input: Qux
def f(x: Foo) = x match {
当返回类型是 ADT 时,是否可以引发类似的未用尽警告,例如在以下实现中f: String => Foo
:
def f(x: String): Foo = x match {
case "bar" => Bar
// warn because we never return Qux
}
解决方案
也许这不是一个真正的答案,但无论如何评论都太长了。
模式匹配和函数返回值是两个不同的东西。前者在类型级别上操作,后者在值级别上操作。当您在 上进行模式匹配时Bar
,您将在类型上进行模式匹配(就像 eg Int
)。但是当您返回时Bar
,您将返回 case 对象值(就像 eg 一样42
)。
满射函数定义为:
对于共域的每个成员y,至少存在一个域成员 x,使得f(x) = y。
现在很容易看出为什么这个检查不可行/不可能。如果你Bar
不是一个案例对象,而是一个类怎么办?例如
final case class Bar(name: String, surname: String, age: Int)
您需要期望Bar
使用的每个可能值(例如,姓名 = “约翰”,姓氏 = “史密斯”,年龄 = 42)。
当然,这不是您想要的;您所描述的是一种场景,其中每个子类型都只有一个居民,因为Bar
和Qux
基本上是枚举,我明白为什么这样的检查对您来说可能有意义。但它必须针对每个(子)类型任意数量的居民的一般情况实施 - 它需要验证 codomain 包含至少一个 type 值Bar
,至少一个 type 值Qux
等,这听起来不很有用。
正如我所说,这并不是一个真正的答案,但我想让您深入了解您要问的究竟是什么。:) 也许有人用反射和/或宏写了一些可以提供这种检查的东西,但据我所知不是。希望使用 Scala 3 枚举,您将永远不需要编写这样的函数。
推荐阅读
- ios - 将应用程序上传到应用程序商店是否需要隐私政策 url
- scikit-learn - MXNetError - 数据集没有以有效的幻数开头
- javascript - 有没有一种方法可以同时添加 onkeypress 和 onclick 事件监听器?
- javascript - 为什么在反应中将数据存储在状态中
- javascript - 为什么 parseInt(021, 8) === 15?
- jquery - 显示每个选择选项的描述
- java - 从 Object.notifyAll 唤醒的线程在哪里无法获得锁?
- python - python中的MATLAB Size等效函数
- linux - 使用 SQL 获取的拆分管道分隔字符串
- c# - WebJob 偶尔会抛出 System.Threading.Tasks.TaskCanceledException