/ / Vincolare i tipi nei generici di Scala per accettare qualsiasi tipo di Int - scala

Vincolare i tipi nei generici di Scala per accettare qualsiasi tipo di Int - scala

Voglio scrivere una funzione vagamente simile a:

def doubleit[A](a: A): A = {a + a}

Ma voglio che "A" significhi qualsiasi tipo di Int, ma non nulla. C'è un modo per dare a Scala un indizio su cosa voglio dire "A"?

def doubleit[A <: Int](a: A): A = {a + a}

viene rifiutato dal compilatore.

risposte:

5 per risposta № 1

In Scala semplice puoi usare la classe di tipo Integral:

scala> def doubleit[A : Integral](a: A): A = implicitly[Integral[A]].plus(a, a)
doubleit: [A](a: A)(implicit evidence$1: Integral[A])A

scala> doubleit(2)
res0: Int = 4

scala> doubleit(BigInt(4))
res1: scala.math.BigInt = 8

Un'altra possibile sintassi:

def doubleit[A](a: A)(implicit ev: Integral[A]): A = ev.plus(a, a)

ev è un nome comunemente usato per quei parametri impliciti.

È anche possibile usare normali operazioni come +, -, ecc. al posto di plus e minus:

def doubleit[A](a: A)(implicit ev: Integral[A]): A = {
import ev._
a + a
}

O come suggerimento di @KChaloux, importazione da Integral.Implicits in anticipo:

import Integral.Implicits._
def doubleit[A : Integral](a: A): A = a + a

Se vuoi che la funzione supporti non solo interi, ma anche DoubleS, BigDecimals, ecc. che puoi usare Numeric invece di Integral:

import Numeric.Implcits._
def doubleit[A : Numeric](a: A): A = a + a

Spiegazione:

scrittura [A : Integral] fa in modo che la funzione riceva un parametro implicito di tipo Integral[A]. Gli impliciti per tutti i tipi di integrale sono già definiti in Scala, quindi puoi usarlo con Int o BigInt immediamente. È anche possibile definire nuovo Integral tipi definendo una nuova variabile implicita di tipo Integral[NewIntegralType] e implementando tutti i metodi necessari.

La chiamata a implicitly[Integral[A]] restituisce questa istanza implicita di Integral[A] che ha un metodo plus per addizione e altri metodi per eseguire altre operazioni sugli integrali.