返回类型密封时的主观性检查 [英] Surjectivity check when return type is sealed
问题描述
Scala 可以在密封类型上的模式匹配不是详尽无遗时发出警告,但是我们可以检查函数是否在返回类型密封时返回所有情况?例如,考虑以下 ADT
Scala can warn when pattern match on a sealed type is not exhaustive, however can we check that a function returns all cases when the return type is sealed? For example, consider the following ADT
sealed trait Foo
case object Bar extends Foo
case object Qux extends Foo
然后函数 f: Foo =>代数数据类型
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 =>;福
:
Is it possible to raise a similar non-exhaustion warning when return type is an ADT such as in the following implementation of f: String => Foo
:
def f(x: String): Foo = x match {
case "bar" => Bar
// warn because we never return Qux
}
推荐答案
也许这不是真正的答案,但无论如何评论都太长了.
Maybe this is not really an answer, but it's too long for a comment anyway.
模式匹配和函数返回值是两件不同的事情.前者在类型级别操作,后者在值级别操作.当您在 Bar
上进行模式匹配时,您就是在类型上进行模式匹配(就像例如 Int
).但是当你返回 Bar
时,你返回的是 case 对象值(就像 42
一样).
Pattern matching and function return values are two different things. Former operates on the type level, latter on the value level. When you pattern match on Bar
, you're pattern matching on the type (just like e.g. Int
). But when you return Bar
, you're returning the case object value (just like e.g. 42
).
满射函数定义为:
对于codomain的每个成员y,至少存在一个成员域的 x,使得 f(x) = y.
For every member y of the codomain, there exists at least one member x of the domain, such that f(x) = y.
现在很容易理解为什么这个检查不可行/不可能.如果你的 Bar
不是一个 case 对象,而是一个类怎么办?例如
Now it's easy to see why this check is not feasible / possible. What if your Bar
wasn't a case object, but a class? E.g.
final case class Bar(name: String, surname: String, age: Int)
您需要期望使用 Bar
的所有可能值(例如 name = "John"、surname = "Smith"、age = 42).
You would need to expect every possible value of Bar
to be used (e.g. name = "John", surname = "Smith", age = 42).
当然,这不是你想要的;您所描述的是每个子类型只有一个居民的情况,因为 Bar
和 Qux
基本上是枚举,我可以理解为什么这样的检查对您有意义.但它必须针对每个(子)类型有任意数量的居民的一般情况来实现 - 它需要验证 codomain 包含至少一个 Bar
类型的值,至少一个值输入 Qux
等等,这听起来不是很有用.
Of course, this is not what you intended; what you described is a scenario where each subtype has exactly one inhabitant, because Bar
and Qux
are basically enums, and I can see why such a check might make sense to you. But it would have to be implemented for the general case of arbitrary number of inhabitants per (sub)type - it would need to verify that codomain contains at least one value of type Bar
, at least one value of type Qux
etc. which doesn't sound very useful.
正如我所说,这并不是真正的答案,但我想让您深入了解您要问的究竟是什么.:) 也许有人用反射和/或宏编写了一些可以提供这种检查的东西,但据我所知.希望使用 Scala 3 枚举您永远不需要编写这样的函数.
As I said, this is not really an answer, but I wanted to give you an insight into what exactly it is that you're asking. :) Perhaps someone wrote something with reflection and/or macros which could provide such a check, but not to my knowledge. Hopefully with Scala 3 enums you will never need to write such a function anyway.
这篇关于返回类型密封时的主观性检查的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!