High-order function of common operations

I have the following Enum

sealed trait DataTyp
case class IntN(n: Int) extends DataTyp
case class FltN(n: Float) extends DataTyp
case class StrL(d: String) extends DataTyp
case class Bool(b: Boolean) extends DataTyp

      

And I want to implement arithmetic, relational and logical operations on them. There is obvious code repetition that could be optimized when doing this. Instead of doing a ridiculous amount of pattern matching to do the right format of operations. Is there a way to make a generic function that I can pass as a parameter when doing pattern matching? Considering that the only thing that changes in most cases with pattern matching is the operational function.

I already know that you can do general arithmetic operations with something like this:

  def add[T](x: T, y: T)(implicit num: Numeric[T]): T = {
    import num._
    x + y
  }

      

But for some reason I cannot use the type parameters as functions (methods only). So what can I do?

+3


source to share


1 answer


There is no good syntax for this, but use the same trick that scala uses for A => B

: use trait.

trait MyGenericOperation {
  def add[T](x: T, y: T)(implicit num: Numeric[T]): T = {
    import num._
    x + y
  }
}

      

You can abstract as well:



trait GenFunctionTTTWithTC[TC[_]] {
  def apply[T: TC](x: T, y: T): T
}

      

Please note that in order to convert all possible signatures of a higher order ( [A, B](A, B) => A)

, [A, B](A, B) => B)

, [A, B, C](A, B) => C)

...) you will need a large number of features.

The projector type plugin implements a certain kind of polymorphic lambda syntax that matches the natural transformation. It probably won't be useful for your use case, I'm just pointing it out to show that people have considered extending the scala syntax to simplify abstraction over parametric type functions.

+1


source







All Articles