2013-02-20 17 views
5

In scalaz, die endo Funktion in Function1Ops wird auf diese Weise versteht umgesetzt:nicht scalaz endo Funktion

def endo(implicit ev: R =:= T): Endo[T] = 
    Endo.endo(t => ev(self(t))) 

Ich bin neugierig, warum in dem Körper Endo.endo Funktion, nicht nur einfach die Selbst nehmen ... als Endo.endo(self), die sich genauso verhält wie Endo.endo(t=> ev(self(t))).

Hier ist meine mimische Implementierung und ich sehe keinen Unterschied zwischen den beiden. Habe ich etwas verpasst?

def endo[R, T](f: R => T)(implicit ev: T =:= R) = (x: R)=> ev(f(x)) 
def endo2[R, T](f: R => T)(implicit ev: T =:= R) = f 

Außerdem, die erste Implementierung fügt einige Overhead zur Laufzeit hinzu?

+0

Ich glaube, der beste Ort, um diese Art von Fragen zu stellen ist die Mailing-Liste: https://groups.google.com/forum/?fromgroups#!forum/scalaz. #[email protected] ist der richtige Ort, um diese Art von Fragen zu stellen. Sie können auch eine Pull-Anfrage an den GitHub-Repo senden: https://github.com/scalaz/scalaz. – folone

Antwort

3

Die Funktion Endo.endo erfordert eine A => A. Der Wert self ist eine Funktion T => R, die nicht der Anforderung Endo entspricht.

Sie könnte theoretisch werfen T => R-T => T aber der ev Parameter erstellt wird, so dass Sie werfen müssen, um nicht aus Versehen und den Fehler, dass T => R-T => T nicht gleich ist.

Sie haben jedoch könnte es wie folgt geschrieben:

def endo(implicit ev: R =:= T): Endo[T] = 
    Endo.endo(self andThen ev) 

Ihre Beispiele kompilieren, da der Rückgabetyp nicht gesetzt ist.

+0

vielen Dank. Ich habe es versäumt, den Rückgabetyp zu berücksichtigen. – chenhry