回流类型密封时的满射性检查

2024-03-09

当密封类型上的模式匹配不详尽时,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 
}

也许这并不是一个真正的答案,但无论如何它对于评论来说太长了。

模式匹配和函数返回值是两个不同的东西。前者运行于type水平,后者在value等级。当您打开模式匹配时Bar,您正在对类型进行模式匹配(就像例如Int)。但当你回来时Bar,您将返回 case 对象值(就像例如42).

满射函数定义为:

对于每一位会员y共域中,至少存在一个成员x的域,使得f(x) = y.

现在很容易看出为什么此检查不可行/不可能。如果你的Bar不是一个案例对象,而是一个类?例如。

final case class Bar(name: String, surname: String, age: Int)

您需要期望每个可能的值Bar要使用的(例如姓名=“John”,姓氏=“Smith”,年龄=42)。

当然,这不是你想要的;你所描述的是一种场景,其中每个亚型只有一个居民,因为Bar and Qux基本上都是枚举,我可以理解为什么这样的检查对你来说可能有意义。但它必须针对每种(子)类型任意数量的居民的一般情况来实现 - 需要验证 codomain 至少包含一个类型值Bar, 至少一个类型值Qux等等,这听起来不是很有用。

正如我所说,这并不是真正的答案,但我想让您深入了解您到底在问什么。 :) 也许有人写了一些带有反射和/或宏的东西可以提供这样的检查,但据我所知并非如此。希望使用 Scala 3 枚举,您将永远不需要编写这样的函数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

回流类型密封时的满射性检查 的相关文章

随机推荐