开发者

Is there a nicer way of lifting a PartialFunction in Scala?

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


condOpt in object scala.PartialFunction. From the scaladoc:

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


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜