返回类型密封时的主观性检查 [英] Surjectivity check when return type is sealed

查看:48
本文介绍了返回类型密封时的主观性检查的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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).

当然,这不是你想要的;您所描述的是每个子类型只有一个居民的情况,因为 BarQux 基本上是枚举,我可以理解为什么这样的检查对您有意义.但它必须针对每个(子)类型有任意数量的居民的一般情况来实现 - 它需要验证 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆