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 № 1In 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 Double
S, BigDecimal
s, 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.