2014-07-22 16 views
5

Come si è visto here, mappa è definitoEsiste un tutorial completo su come utilizzare questo tipo di tipizzazione strutturale?

in un modo un po 'funky

Per completezza, ecco il codice:

implicit def FunctionFunctor[R] = new Functor[({type l[a] = R=>a})#l] { 
    def map[A, B](fa: R => A)(f: A => B) : R => B = (x => f(fa(x))) 
} 

Più concretamente - new Functor[({type l[a] = R=>a})#l]

Penso di sapere cosa sta succedendo, ma non posso dire onestamente che capisco perfettamente t lui concetto. E poiché non vi è alcun suggerimento, non posso chiamare Google il termine (semplicemente non lo so per google). Esiste qualche tutorial (o recensione o altro) in cui ciò viene spiegato con un migliore livello di detalizzazione? Apprezzerei ancora di più qualcuno potrebbe spiegarlo proprio qui nelle risposte.

risposta

8

Questo è un caso speciale di tipizzazione strutturale, ma chiamato "tipo lambda", se si cerca type lambda scala google vi darà alcuni risultati.

In breve, è utilizzato in modo simile alle funzioni parzialmente applicate.

def x(a:Int, b:Int):Int = a * b 
val x10 = x(10, _:Int) 
x10(2) // 2 

Un esempio con tipi.

type IntEither[B] = Either[Int, B] 
val y:IntEither[String] // Either[Int, String] 

In alcuni casi i metodi o classi si aspettano un tipo con un solo parametro

class Test[F[_]] 

Non è possibile dare alla classe Test un Either perché Test si aspetta un tipo con 1 parametro e Either ha 2. In per poter passare in un Either possiamo parzialmente applicarlo

type X[B] = Either[Int, B] 
new Test[X] 

Un modo alternativo di scrivere che è come questo:

type X = { 
    type T[x] = Either[Int, x] 
} 

new Test[X#T] 

Invece di creare un tipo di alias, possiamo anche definire il tipo X anonimo

new Test[({type T[x] = Either[Int, x]})#T] 

Questi tutti dare un'istanza di tipo Test[Either[Int, x]].


Modifica

Il vostro esempio potrebbe essere la seguente:

type PartiallyTypedFunction[R] = { 
    type T[x] = R => x 
} 

implicit def FunctionFunctor[R] = 
    new Functor[PartiallyTypedFunction[R]#T] { 
    def map[A, B](fa: R => A)(f: A => B): R => B = (x => f(fa(x))) 
    } 
+0

wow, è così semplice? : D – tkroman

+0

In effetti, sembra troppo complicato. Ecco perché di solito creo un alias di tipo o anche un tratto o una classe per evitare di usare quella sintassi orribile. – EECOLOR

+0

@cdshines Ho aggiunto un esempio del codice che hai postato usando un alias di tipo. – EECOLOR

Problemi correlati