Universal type function for summing numbers based on their types

Assume that x and y of the same type and can be either Boolean, Intor Double. Here is the function I want to write:

f(x, y) = 
   - if x == Boolean ==>   !x 
   - if x == Integer or x == Double ==> x+ y 

One way to do this could be as follows. I was wondering if anyone has any better ideas on this.

def fun[T](x: T, y: T): T { 
   x match { 
       case xP: Boolean => !xP 
       case xP: Double => y match { case yP: Double =>  xP + yP }
       case xP: Int => y match { case yP: Int =>  xP + yP }
   }
}

I am not satisfied with the fact that xthey yhave the same type. I do not need two match-cases; correctly?

Two other things:

  • Is it simple enough to set [T <: Int, Double, Boolean]to restrict a type to only three types?
  • The type of output should be again T.
+4
source share
3 answers

, . - :

trait Add[A] {
  def apply(a: A, b: A): A
}

object Add {
  implicit val booleanAdd: Add[Boolean] = new Add[Boolean] {
    def apply(a: Boolean, b: Boolean): Boolean = !a
  }

  implicit def numericAdd[A: Numeric]: Add[A] = new Add[A] {
    def apply(a: A, b: A): A = implicitly[Numeric[A]].plus(a, b)
  }
}

Add[X] , X. "" Add[X] X, . Boolean , scala.math.Numeric ( , ). Int Double, numericAdd Add[Int] Add[Double].

fun :

def fun[T: Add](x: T, y: T) = implicitly[Add[T]].apply(x, y)

:

scala> fun(true, false)
res0: Boolean = false

scala> fun(1, 2)
res1: Int = 3

scala> fun(0.01, 1.01)
res2: Double = 1.02

: , . , MatchError , . fun, :

scala> fun("a", "b")
<console>:14: error: could not find implicit value for evidence parameter of type Add[String]
       fun("a", "b")
          ^

"" (.. , case x: X => ...) - Scala, . .

+10

, Summable[A] , Summable. , .

trait Summable[A] {
  def +(a: A, b: A): A
}

object Summable {
  implicit object SummableBoolean extends Summable[Boolean] {
    override def +(a: Boolean, b: Boolean) = !a
  }
  implicit object SummableInt extends Summable[Int] {
    override def +(a: Int, b: Int) = a + b
  }
  implicit object SummableDouble extends Summable[Double] {
    override def +(a: Double, b: Double) = a + b
  }
}

def fun[A](a: A, b: A)(implicit ev: Summable[A]) =
  ev.+(a, b)

val res1 = fun(true, true) // returns false
val res2 = fun(1, 3) // returns 4
val res3 = fun(1.5, 4.3) // returns "5.8"

. , , , , . , , , . . boolean , .

+3

First of all, your example is syntactically incorrect (missing casein match). The simpler and shorter way that I can see now is something like this:

def fun[T <: AnyVal](x: T, y: T) = {
  x match {
    case xP: Boolean => !xP
    case xP: Double => xP + y.asInstanceOf[Double]
    case xP: Int => xP + y.asInstanceOf[Int]
  }
}

fun(1, 2)            // res0: AnyVal = 3
fun(2.5, 2.6)        // res1: AnyVal = 5.1
fun(true, false)     // res2: AnyVal = false
-1
source

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


All Articles