2016-02-19 18 views
9

E 'in qualche modo possibile dichiarare qualcosa comedichiarare una funzione `type` con` parametri implicit`

type F = (Int, Boolean)(implicit String) => Unit 

a Scala?

+0

Spiacente ho cancellato il mio commento, che era "si può fare di tipo f = (Int, booleano) => (String) => Unità comunque ". Hai ragione nel dire che non funziona con impliciti, suppongo che sia perché non devi dipendere da loro nei tuoi tipi. Una funzione che accetta un Int e un booleano è una funzione che accetta un Int e un Booleano indipendentemente dagli impliciti nello scope. modifica: Ok, ven ha risposto di seguito, un metodo non è una funzione e le funzioni non hanno impliciti –

risposta

18

V'è una distinzione molto importante a Scala tra "funzione" e "metodo":

funzioni sono valori, e non possono prendere argomenti per nome, non può essere polimorfico, non può essere variadic , non può essere sovraccaricato e non può avere parametri impliciti. Mentre i metodi possono avere questi, non possono essere passati in giro come valori.

tipi di funzione sono pochi tratti nella libreria standard, della forma seguente:

trait FunctionN[T1, ..., TN, R] { 
    def apply(x1: T1, ..., xN: TN): R 
} 

Si noti come il metodo di apply in questi tipi non non dispone di un elenco di parametri implicita. Pertanto, le funzioni non avranno mai parametri impliciti.

Quindi, se si desidera passare "funzioni" che accettano parametri impliciti, è necessario creare il proprio tratto:

trait Function2I1[T1, T2, I1, R] { 
    def apply(a1: T1, a2: T2)(implicit i1: I1): R 
} 

type F = Function2I1[Int, Boolean, String, Unit] 

Ora è possibile creare istanze di tipo F (anche se non con la sintassi lambda lucido):

val f = new F { 
    override def apply(x: Int, y: Boolean)(implicit z: String): Unit = ??? 
} 
implicit val x = "hi" 
f(1, true) // implicitly passes x 

Se si desidera funzioni al curry senza parametri impliciti, basta scrivere (Int, Boolean) => String => Unit.

Se si desidera convertire un metodo per una funzione, utilizzare un lambda:

class A { 
    def f(a: String)(implicit b: String): String = a + b 
} 
val a = new A 
val m = a.f(_) // takes the implicit in this scope 
Problemi correlati