Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
Prochain SlideShare
Chargement dans…5
×

# Traversals for all ocasions

1 575 vues

Publié le

Scalar 2018

Publié dans : Logiciels
• Full Name
Comment goes here.

Are you sure you want to Yes No

### Traversals for all ocasions

1. 1. TRAVERSALS FOR ALL OCCASIONS Luka Jacobowitz
2. 2. Software Developer at codecentric Co-organizer of ScalaDus and IdrisDus Maintainer of cats, cats-effect, cats-mtl, OutWatch Enthusiastic about FP About me
3. 3. Motivation ● Traversable is my favorite type class ● Not enough people know about it ● Even less people know about some of the less common traversals out there ● Have some fun while learning!
4. 4. Motivation
5. 5. Teaser How do you create a List of Http Requests run them all in parallel and if errors occur accumulate them? userIdList.parTraverse(request).value
6. 6. Traverse [T[_]: Traverse, F[_]: Applicative, A]: T[F[A]] => F[T[A]] E.g. List[Future[A]] => Future[List[A]] Vector[Option[A]] => Option[Vector[A]]
7. 7. Traverse [T[_]: Traverse, F[_]: Applicative, A]: T[F[A]] => F[T[A]] Traverse runs an action(F[_]) for every element in a data structure (T[_]), and accumulates the results.
8. 8. Traverse trait Applicative[F[_]] { def map2[A, B, C](fa: F[A], fb: F[B])(f: (A, B) => C): F[C] def pure[A](a: A): F[A] } Applicatives allow us to combine two or more independent values inside a context.
9. 9. Traverse trait Traverse[T[_]] { def sequence[F[_]: Applicative, A](tfa: T[F[A]]): F[T[A]] def traverse[F[_]: Applicative, A, B](ta: T[A], f: A => F[B]): F[T[B]] } t.traverse(f) <-> t.map(f).sequence
10. 10. Traverse List[Future[A]] => Future[List[A]] Vector[Option[A]] => Option[Vector[A]] Either[E, IO[A]] => IO[Either[E, A]] type EitherE[A] = Either[E, A] List[Validated[E, A]] => Validated[E, List[A]]
11. 11. FoldMap trait Foldable[T[_]] { def foldMap[A, M: Monoid](ta: T[A], f: A => M): M def fold[M: Monoid](ta: T[M]): M } t.foldMap(f) <-> t.map(f).fold def foldMap[A, M: Monoid](ta: T[A], f: A => M): M = ta.traverse(a => Const(f(a))).getConst
12. 12. NonEmpty trait Reducible[T[_]] { def reduceMap[A, S: Semigroup](ta: T[A], f: A => S): S def reduce[S: Semigroup](ta: T[S]): S } trait NonEmptyTraverse[T[_]] { def nonEmptyTraverse[F[_]: Apply](ta: T[A], f: A => F[B]): F[T[B]] def nonEmptySequence[F[_]: Apply](ta: T[F[A]]): F[T[A]] } t.reduceMap(f) <-> t.map(f).reduce t.nonEmptyTraverse(f) <-> t.map(f).nonEmptySequence
13. 13. NonEmpty def maximum[A: Order](nel: NonEmptyList[A]): A = reduceMap(nel)(Max) def minimum[A: Order](nel: NonEmptyList[A]): A = reduceMap(nel)(Min)
14. 14. NonEmpty def countWords(text: String): Map[String, Int] = words.split(" ").groupBy(identity).mapValues(_.length) val lines: NonEmptyList[String] val result: Map[String, NonEmptyList[Int]] = lines.nonEmptyTraverse(countWords)
15. 15. Commutativity trait UnorderedFoldable[T[_]] { def unorderedFold[M: CommutativeMonoid](ta: T[M]): M } trait UnorderedTraverse[T[_]] { def unorderedSequence[F[_]: CommutativeApplicative, A] (ta: T[F[A]]): F[T[A]] }
16. 16. Commutativity CommutativeMonoid: a |+| b <-> b |+| a E.g: Int, Set[String]
17. 17. Commutativity val users: HashSet[User] val result = users.unorderedFoldMap(_.billableHours)
18. 18. Commutativity CommutativeApplicative: map2(fa, fb)((a, b) => f(a, b)) <-> map2(fb, fa)((b, a) => f(a, b)) fa *> fb <-> fb <* fa E.g. Option, ValidatedNes
19. 19. Commutativity type ValidatedNes[E, A] = Validated[NonEmptySet[E], A] val result: ValidatedNes[Error, RDD[User]] = users.unorderedTraverse(validate)
20. 20. FlatTraverse trait Traverse[T[_]] { def flatTraverse[G[_]: Applicative, A, B](ta: T[A]) (f: A => G[T[B]])(implicit T: FlatMap[T]): G[T[B]] } ta.traverse(f).map(_.flatten) <-> ta.flatTraverse(f)