2013-08-11 7 views
5

Czy ktoś mógłby mi pomóc z poniższymi fragmentami kodu z książki?Przykładowy przykład projekcji z "Scala w akcji" (rozdział 8)

trait Mapper[F[_]] { 
    def fmap[A, B](xs: F[A], f: A => B): F[B] 
} 

def VectorMapper = new Mapper[Vector] { 
    def fmap[A, B](xs: Vector[A], f: A => B): Vector[B] = xs map f 
} 

To było proste: określenie cechą zastosowania wyższej-kinded typu F[_] do zastosowania wszelkich typów „pojemnik” podobne, a następnie beton mapowania dla Vector.

Potem idzie trudna część. Mapper dla Either. Rozumiem, że {type E[A] = Either[X, A]} jako blok kodu i ({type E[A] = Either[X, A]})#E jako odwzorowanie tego typu aliasu E z anonimowego bloku kodu i przez tego autora "ukrywa" obecność X dla cechy Mapper, ponieważ cecha działa na jednym typie Parametr "typy kontenerów" - i jesteśmy zainteresowani A, tj. Right.

def EitherMapper[X] = new Mapper[({type E[A] = Either[X, A]})#E ] { 
    def fmap[A, B](r: Either[X, A], f: A => B): Either[X, B] = r match { 
     case Left(a) => Left(a) 
     case Right(a) => Right(f(a)) 
    }  
} 

Pytanie: Dlaczego potrzebujemy X w def EitherMapper[X] = części?

Dzięki za szczegóły.

Odpowiedz

4

Albo jest zależna od dwóch typów, na przykład Either[Int, String]

EitherMapper jest konstruktorem typu, który jest zależny tylko od jednego rodzaju, więc gdy masz EitherMapper[Int], masz do czynienia z Either[Int, A] i A został rozwiązany w część Mapper, w ten sposób możesz mieć dowolną funkcję A=>B, ponieważ pierwszy typ Either jest już obecny dla Mappera i zwrócisz Either[X, B].

Rzeczywiście typ E [A] jest równoważny Albo [X, A], masz tylko jeden stopień swobody w odniesieniu do typów!

val right: Either[Boolean, String] = Right("test") 
val left: Either[Boolean, String] = Left(false) 

println(EitherMapper.fmap(right, (s: String) => s.length)) 
> Right(4) 
println(EitherMapper.fmap(left, (s: String) => s.length)) 
> Left(false) 

W tym przypadku typ jest EitherMapper[Boolean] i typ FMapy jest fmap[String, Integer], akceptuje Either[Boolean, String] i powrót Either[Boolean, Integer].

Jak widać typ FMapy nie mówi nic na X część typu Either[X, A] więc w końcu można korzystać z funkcji (s: String) => s.length) dla innych EitherMapper[X] rodzajów, w prostych słowach „left” część każdy typ może być dowolny, i jest to część "X" konstrukcji typu.

Mam nadzieję, że teraz będzie jaśniej!

+1

Vincenzo, cześć. Czy mógłbyś z przyjemnością zilustrować użycie 'EitherMapper', może to uczyniłoby to jaśniejszym? Pytam o to, ponieważ, powiedzmy, dla 'VectorMapper' jest to proste jak' val v = VectorMapper.fmap (someVectorOfInts, _ => _ * 2) ' – Max

+0

Tak, po prostu poczekaj chwilę, bo muszę wziąć mój laptop, w którym zainstalowałem Scala –

+0

Dodano przykład !!! –

Powiązane problemy