Is there a better way to raise PartialFunction in Scala?

I sometimes come across the following pattern, where I essentially have a PartialFunction[SomeType,AnotherType] , and want to consider it as Function[SomeType,Option[AnotherType] , for example:

 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 such a way as to avoid the default case and wrap the result in Some , where it is defined? The best I've come up with so far:

 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 this without defining an intermediate function? I have already tried different things in accordance with the following principles, but have not yet received a compilation:

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

condOpt in a scala.PartialFunction object. From the skaladok:

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

Not as much answer as an explanation of why huynhjl answer is correct ...

Part of your confusion is that you are trying to execute a def partial function. All this is done to create a method that returns a PartialFunction object when you can also directly create an object:

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

Although I personally prefer to use titration:

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

In any case, you need to specify the input type, so you need to specify the exact signature of the PartialFunction . I know that it seems that it should be possible to do this, but, alas, this, unfortunately, is not so!

Using the given version, you can then define and raise everything 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 a better solution, though, since it allows the specialist to do most of this work for you, leaving much cleaner code :)

+4
source

Source: https://habr.com/ru/post/902815/


All Articles