Why there is no partial chain function method other than orElse

I ask this question because I need functionality similar to a andThennormal function (but still consistent with the semantics of a partial function). What I mean should be explained as follows:

andThen for functions:

val x: Int => Int = ???
val y: Int => Double = ???
val z: Int => Double = x andThen y

andThenfor a partial function (differently, since it andThenalready exists with different semantics):

val x: PartialFunction[A, B] = ???
val y: PartialFunction[B, C] = ???
val z: PartialFunction[A, C] = x andThenExtact y

Where is zdetermined by a parameter a: Athat has the following properties:

  • x is defined in

  • y is defined in x (a)

I came up with the following extension, which should in principle provide the desired functionality:

type =>?[-A, +B] = PartialFunction[A, B]

class RichPartialFunction[A, B](private val lhs: A =>? B) extends AnyVal {

  def andThenWiden[BB >: B, R](widening: BB =>? R): A =>? R = {
    val InnerMatcher = matchArgument(lhs)
    val pf: A =>? R = {
      case InnerMatcher(res) if widening.isDefinedAt(res) =>
        widening(res)
    }
    pf
  }

  def andThenExact[R](pipeTo: B =>? R): A =>? R = {
    val InnerMatcher = matchArgument(lhs)
    val pf: A =>? R = {
      case InnerMatcher(res) if pipeTo.isDefinedAt(res) =>
        pipeTo(res)
    }
    pf
  }

}
private def matchArgument[A, B](fun: A =>? B): PartiallyUnapply[A, B] = new PartiallyUnapply(fun)

private class PartiallyUnapply[A, B](private val fun: A =>? B) extends AnyVal {
  def unapply(arg: A): Option[B] = {
    fun.andThen(Some(_)).applyOrElse(arg, (_: A) => None)
  }
}

My question is the best solution to this problem, and if my approach is bad, then how can I replace x andThenExtact yin my code?

+4

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


All Articles