Pomijając szczegóły implementacji przez chwilę, map
jestandThen
dla funkcji (pod instancji funktora dla A => ?
) i tak naprawdę nie zrobić wiele sensu mówić o preferowaniu jednej z drugiej, jeśli mówimy o funkcjach, a nie o wyższym poziomie abstrakcji.
Jakie metody, takie jak map
(i klasy typu, takie jak Functor
bardziej ogólnie) pozwalają nam to zrobić, są abstrakcyjne dla określonych typów lub typów konstruktorów. Załóżmy, że chcemy napisać metodę incrementResult
, która działa na przykład na A => Int
lub Kleisli[Option, A, Int]
. Typy te nie mają nic wspólnego, jeśli chodzi o dziedziczenie (krótkie z AnyRef
, który jest bezużyteczny), ale A => ?
i Kleisli[Option, A, ?]
są oba funktory, więc możemy napisać:
import scalaz._, Scalaz._
def incrementResult[F[_]: Functor](f: F[Int]): F[Int] = f.map(_ + 1)
a następnie używać go w ten sposób (zauważ, że używam kind-projector uproszczenie składni typ a bit):
scala> val plainOldFuncTriple: Int => Int = _ * 3
plainOldFuncTriple: Int => Int = <function1>
scala> val optionKleisliTriple: Kleisli[Option, Int, Int] = Kleisli(i => Some(i * 3))
optionKleisliTriple: scalaz.Kleisli[Option,Int,Int] = Kleisli(<function1>)
scala> val f = incrementResult[Int => ?](plainOldFuncTriple)
f: Int => Int = <function1>
scala> val k = incrementResult[Kleisli[Option, Int, ?]](optionKleisliTriple)
k: scalaz.Kleisli[Option,Int,Int] = Kleisli(<function1>)
scala> f(10)
res0: Int = 31
scala> k(10)
res1: Option[Int] = Some(31)
W tym przypadku konkretnie istnieją lepsze sposoby wdrożenia tej operacji, ale to pokazuje ogólną ideę, nie mogliśmy napisać metoda pojedyncza, która działa dla zwykłych funkcji i strzałek Kleisli przy użyciu andThen
, ale możemy z dodatkowym poziomem abstrakcji, który daje nam map
.
Tak, aby odpowiedzieć na Twoje pytanie-you'd korzystanie map
jeśli chcesz streszczenie na wszystkich konstruktorów typu, które mają wystąpienie funktora, ale jeśli pracujesz konkretnie z funkcji, map
jestandThen
, i-jak długo ponieważ wciąż odkładamy szczegóły implementacji - nie ma znaczenia, który z nich wybierzesz.
Przypis: the map
że syntax
pakiet Scalaz daje ci dla wartości typów, które instancje funktora jest zaimplementowany jako metodę rozszerzenia, więc nie ma odrobinę napowietrznych (zarówno w czasie kompilacji i wykonywania) zaangażowana w użyciu map
zamiast andThen
dla funkcji. Jeśli pracujesz tylko z funkcjami i nie potrzebujesz dodatkowej abstrakcji, równie dobrze możesz przejść z andThen
.
Studnia 'map' działa na dowolnym funktorze, a nie tylko na funkcjach. – Bergi
Myślałem o tym też. Mogę więc mapować listę opcji i listę funktora, ale nie potrafię wymyślić, jak utworzyć listę funktorów. – thlim