È possibile fare qualcosa di simile al seguente?Scala: passa la funzione al curry come parametro
def takeCurriedFnAsArg(f: (Int)(implicit MyClass) => Result)
È possibile fare qualcosa di simile al seguente?Scala: passa la funzione al curry come parametro
def takeCurriedFnAsArg(f: (Int)(implicit MyClass) => Result)
Sì, è possibile.
Quando si ha il secondo parametro al curry contrassegnato come implicit
, la funzione sembra essere non di tipo
Int => (MyClass => Result) => ResultOfFunction
che sarebbe se il parametro della funzione di ordine superiore al curry era un parametro regolare; invece, sembra che questo:
Int => ResultOfFunction
Ecco un rapido esempio:
scala> def curriedFn(i : Int)(implicit func : String => Int) : Boolean = (i + func("test!")) % 2 == 0
curriedFn: (i: Int)(implicit func: String => Int)Boolean
scala> implicit val fn : String => Int = s => s.length
fn: String => Int = <function1>
scala> curriedFn _
res4: Int => Boolean = <function1>
Come si può vedere, il parametro implicit
ottenuto 'eliminato'. Perché e come? Questa è una domanda per qualcuno più esperto di me. Se dovessi indovinare, direi che il compilatore sostituisce direttamente il parametro con il valore implicito, ma potrebbe benissimo essere falso.
In ogni caso, digressioni a parte, ecco un esempio molto rilevanti per la vostra situazione:
scala> def foo(func : Int => Boolean) = if(func(3)) "True!" else "False!"
foo: (func: Int => Boolean)String
scala> foo(curriedFn)
res2: String = True!
Ora, se il secondo parametro funzione non era implicito:
scala> def curriedNonImplicit(i : Int)(fn : String => Int) : Boolean = (i + fn("test!")) % 2 == 0
curriedNonImplicit: (i: Int)(fn: String => Int)Boolean
scala> curriedNonImplicit _
res5: Int => ((String => Int) => Boolean) = <function1>
Come si può vedere, il tipo della funzione è un po 'diverso. Ciò significa che la soluzione avrà un aspetto diverso anche:
scala> def baz(func : Int => (String => Int) => Boolean) = if(func(3)(s => s.length)) "True!" else "False!"
baz: (func: Int => ((String => Int) => Boolean))String
scala> baz(curriedNonImplicit)
res6: String = True!
È necessario specificare la funzione direttamente all'interno del metodo, in quanto non è stato implicitamente fornito prima.
Grazie per aver spiegato entrambi i casi (con e senza implicito) con esempi completi. – Prasanna