在 Scala 中是否有更好的方法来提升 PartialFunction?

发布于 2024-10-12 16:08:39 字数 895 浏览 3 评论 0原文

我偶尔会遇到以下模式,其中我本质上有一个 PartialFunction[SomeType,AnotherType],并且希望将其视为 Function[SomeType,Option[AnotherType],例如:

def f(s:SomeType):Option[AnotherType] = s match {
  case s1:SubType1 => Some(AnotherType(s1.whatever))
  case s2:SubType2 => Some(AnotherType(s2.whatever))
  case _ => None
}

有没有一种方法可以避免默认情况并将结果包装在定义的 Some 中?到目前为止我想到的最好的办法是:

def f(s:SomeType):Option[AnotherType] = pf.lift(s)
def pf:PartialFunction[SomeType,AnotherType] = {
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
}

有没有一种方法可以在不定义中间函数的情况下做到这一点?我已经尝试了以下各种方法,但还没有任何东西可以编译:

def f:Function[SomeType,Option[AnotherType]] = {
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
}.lift

I occasionally come across the following pattern, where I essentially have a PartialFunction[SomeType,AnotherType], and want to treat it as a Function[SomeType,Option[AnotherType], eg:

def f(s:SomeType):Option[AnotherType] = s match {
  case s1:SubType1 => Some(AnotherType(s1.whatever))
  case s2:SubType2 => Some(AnotherType(s2.whatever))
  case _ => None
}

Is there a way to write the above function in a way that avoids the default case and wrapping the result in Some where it's defined? The best I've come up with so far is this:

def f(s:SomeType):Option[AnotherType] = pf.lift(s)
def pf:PartialFunction[SomeType,AnotherType] = {
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
}

Is there a way to do it without defining an intermediate function? I've already tried various things along the lines of the following, but haven't got anything to compile yet:

def f:Function[SomeType,Option[AnotherType]] = {
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
}.lift

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

意中人 2024-10-19 16:08:39

对象 scala.PartialFunction 中的 condOpt。来自 scaladoc:

def onlyInt(v: Any): Option[Int] = condOpt(v) { case x: Int => x }

condOpt in object scala.PartialFunction. From the scaladoc:

def onlyInt(v: Any): Option[Int] = condOpt(v) { case x: Int => x }
も让我眼熟你 2024-10-19 16:08:39

与其说是一个答案,不如说是对为什么 huynhjl 的答案是正确的解释......

你的部分困惑是你试图定义一个部分函数。这一切所做的就是创建一个返回 PartialFunction 对象的方法,您也可以直接创建该对象:

val pf: PartialFunction[SomeType,AnotherType] = {
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
}

虽然我个人更喜欢使用类型归属:

val pf = {
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
} : PartialFunction[SomeType,AnotherType]

无论哪种方式,您都必须指定输入的内容类型是,因此您必须给出 PartialFunction 的准确签名。我知道感觉应该可以推断出这一点,但遗憾的是事实并非如此!

使用归属版本,您可以在同一个位置定义和提升所有内容:

val pf = ({
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
} : PartialFunction[SomeType,AnotherType]).lift

PartialFunction.condOpt 是更好的解决方案,因为它允许推理器为您完成大部分工作,从而更加干净代码 :)

Not so much an answer, as an explanation of why huynhjl's answer is correct...

Part of your confusion is that you're trying to def a partial function. All this does is to create a method that returns a PartialFunction object, when you may as well create the thing directly:

val pf: PartialFunction[SomeType,AnotherType] = {
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
}

Though I personally prefer to use type ascription:

val pf = {
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
} : PartialFunction[SomeType,AnotherType]

Either way, you have to specify what the input type is, so you have to give the exact signature of the PartialFunction. I know it feels like it should be possible to to infer this but, alas, that is sadly not the case!

Using the ascribed version, you can then define and lift all in the same place:

val pf = ({
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
} : PartialFunction[SomeType,AnotherType]).lift

PartialFunction.condOpt is the better solution though, as it allows the inferencer to do most of this work for you, leaving much cleaner code :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文