Chaining PartialFunctions with andThen in Scala

前端 未结 3 1295
暗喜
暗喜 2020-12-20 12:56

Let us reuse examples from Daily scala :

type PF = PartialFunction[Int,Int]

val pf1 : PF = {case 1 => 2}                      

val pf2 : PF = {case 2 =&         


        
3条回答
  •  时光取名叫无心
    2020-12-20 13:45

    If you look at andThen:

    def andThen[C](k: (B) => C): PartialFunction[A, C]
    

    This composes the receiver with a function and not a partial function. That is, k is expected to be fully defined, it doesn't have isDefinedAt. Therefore, the resulting partial function does not need to alter the behaviour of isDefinedAt, it will still just has to consult the first partial function.

    You could write your own extension that composes two partial functions:

    implicit class ComposePartial[A, B](pf: PartialFunction[A, B]) {
      def collect[C](that: PartialFunction[B, C]): PartialFunction[A, C] =
        new PartialFunction[A, C] {
          def apply(a: A): C = that(pf(a))
          def isDefinedAt(a: A) = pf.isDefinedAt(a) && {
            val b = pf(a)
            that.isDefinedAt(b)
          }
        }
    }
    
    pf1 collect pf2 isDefinedAt(1)  // true
    pf1 collect pf3 isDefinedAt(1)  // false
    

    The problem is that you have to invoke pf(a), so given that Scala doesn't enforce purity, you may end up executing side effects unwantedly.

提交回复
热议问题