Scala non ha funzioni polimorfiche come ad esempio Haskell. Un tipo di funzione è sempre concreto. Solo i metodi possono essere polimorfici. Ciò significa, purtroppo, che il tuo tipo ipotetico (x: Foo) => x.Bar
non è esprimibile in Scala.
Questo diventa evidente quando si converte metodi generici a funzioni: tutte le informazioni sul tipo è perduto:
scala> def foo[Bar](x: Bar): Bar = ???
foo: [Bar](x: Bar)Bar
scala> foo _
res1: Nothing => Nothing = <function1>
Si potrebbe avere anche notato che scala non riescono a convertire i metodi con i tipi dipendenti alle funzioni. Ecco perché è impossibile soddisfare il vostro tipo ipotetico:
scala> def foo(x: Foo): x.Bar = ???
foo: (x: Foo)x.Bar
scala> foo _
<console>:10 error: method with dependent type (x: Foo)x.Bar cannot be converted
to function value.
vedono anche this e this domande.
Esistono tuttavia diverse soluzioni al problema. Uno sarebbe per incapsulare il metodo dipendente digitato in un tratto aiutante:
trait FooFunc {
def apply(x: Foo): x.Bar
}
def compareOutput(x1: Foo, x2: Foo)(f: FooFunc)(comparer: ...) = {
val y1 = f(x1)
val y2 = f(x2)
comparer(y1,y2)
}
È quindi possibile creare istanze di FooFunc che è possibile passare nel vostro metodo di compareOutput
.
fonte
2014-04-04 14:35:38
Vedere ad esempio [come Miles Sabin utilizza i tipi di metodo dipendenti in Shapeless] (https://github.com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/syntax/hlists.scala) . –
Non penso che sia rilevante. Vuole essere in grado di definire un tipo di funzione (al contrario della sola definizione di un metodo) in cui il tipo di ritorno dipende dal valore dell'argomento. Credo che questo sia al momento impossibile. Anche se riesci a definire un tipo che corrisponda all'intento di OP, non penso che potresti passare un metodo come argomento 'f' perché eta-expansion non supporta tipi di metodi dipendenti. Vedi https://issues.scala-lang.org/browse/SI-4751. Questo forzerebbe a definire quelle "funzioni dipendenti" in un modo piuttosto scomodo, come estendere un tratto personalizzato e implementare il suo metodo "apply" –
@ RégisJean-Gilles: hai ragione - forse stavo leggendo troppo velocemente. Quello che descrivi potrebbe essere fatto con i valori delle funzioni polimorfiche di Shapeless, ma non con le funzioni di Scala di vaniglia. –