Upgrade to Pro — share decks privately, control downloads, hide ads and more …

cats very light intro

bs76
November 11, 2017

cats very light intro

Very light cats intro, take with grain of salt.

bs76

November 11, 2017
Tweet

More Decks by bs76

Other Decks in Programming

Transcript

  1. Coordinates • https://typelevel.org/cats/ • GitHub: https://github.com/typelevel/cats Learning resources: • http://eed3si9n.com/herding-cats/

    • http://learnyouahaskell.com/chapters <-- start here Cheatsheet • https://arosien.github.io/cats-cheatsheets/typeclasses.pdf
  2. What is it ? • A library • It is

    to functional what design patterns are to OOP • Design patterns in OOP: Factory, Singleton, Bridge, Proxy, Flyweight ... • Works but reusability is bound to OOP concepts • FP – different approach
  3. FP approach • Algebraic data types – model of the

    domain • Algebras – system of how 'things' relate • Types – parametricity • Functional patterns: – Typed – Parametric imply – Agnostic – Reusable
  4. Typeclasses • Semigroup[T] – combine - |+| • Monoid[T] requires

    Semigroup[T] – Adds Zero • Fold over T where Monoid[T] exists: Foldable[List].fold(List(1,2 ,3)) val F = Foldable[List] F.fold(l) scala> List(1, 2, 3) |+| List(4, 5, 6) res2: List[Int] = List(1, 2, 3, 4, 5, 6) scala> "one" |+| "two" res3: String = onetwo • How ? implicit def optionMonoid[A](implicit ev: Semigroup[A]): Monoid[Option[A]] = new Monoid[Option[A]] { def empty: Option[A] = None def combine(x: Option[A], y: Option[A]): Option[A] = x match { case None = y case Some(xx) = y match { case None = x case Some(yy) = Some(ev.combine(xx,yy)) } } }
  5. Functor • Anything we can map over trait Functor[F[_]] {

    def map[A, B](fa: F[A])(f: A = B): F[B] } • Example scala> import cats._, cats.data._, cats.implicits._ import cats._ import cats.data._ import cats.implicits._ scala> Functor[List].map(List(1, 2, 3)) { _ + 1 } res0: List[Int] = List(2, 3, 4)
  6. Applicative • N independent evaluations, requires Functor[F[_]] • mapN, apN,

    liftN • Example: @ val A = Applicative[Option] A: Applicative[Option] = cats.instances.OptionInstances$$anon$1@598f6c93 @ A.map3(1.some,2.some,4.some){ (a,b,c) = a |+| b |+| c } res3: Option[Int] = Some(7) case class ThreeNumbers(a:Int,b:Int,c:Int) @ A.map3(1.some,2.some,4.some)(ThreeNumbers) res5: Option[ThreeNumbers] = Some(ThreeNumbers(1, 2, 4)) @ A.map3(1.some,2.some,none)(ThreeNumbers) res5: Option[ThreeNumbers] = None • Validations – cats has good support • Futures – scalajs – need to fetch N json payloads and display them all
  7. Applicative cont. • pure[A](x: A): F[A] - put into an

    F[_], e.g. Option,List…. • sequence[G[_], A](as: G[F[A]])(implicit G: cats.Traverse[G]): F[G[A]] – List[Option] -> Option[List] • traverse[A, G[_], B](value: G[A])(f: A => F[B])(implicit G: cats.Traverse[G]): F[G[B]] – A.traverse(List(1,2,3)){ x => x.some } -> Option[List[_]]
  8. Monad • Has flatMap, requires Applicative[F[_]] • FlatMap means dependent

    application val lngth = (s:String) = s.length.some @ "aaa".some > lngth res9: Option[Int] = Some(3) @ val validStr = (s:String) = if(s.trim.isEmpty) None else s.trim.some @ val atLeastX = (s:String,minLen:Int) = if(s.length < minLen) None else s.some @ val minLen5 = (s:String) = atLeastX(s,5) @ " aha ".some > validStr > minLen5 res15: Option[String] = None @ " five is 5 ".some > validStr > minLen5 res16: Option[String] = Some("five is 5")
  9. Laws • There are laws defined typeclasses must abide •

    e.g. associativity, right association, transitivity etc (per typeclass) • There's a checker • Roll your own – easily check
  10. Is there more ? Band BoundedSemilattice CommutativeGroup CommutativeMonoid CommutativeSemigroup Eq

    Group Semigroup Monoid Order PartialOrder Semilattice Alternative Applicative ApplicativeError Apply Bifoldable Bimonad Bitraverse Cartesian Cofl atMap Comonad ContravariantCartesian FlatMap Foldable Functor Inject InvariantMonoidal Monad MonadError MonoidK NotNull Reducible SemigroupK Show ApplicativeAsk Bifunctor Contravariant Invariant Profunctor Strong T raverse Arrow Category Choice Compose Cats T ype Classes kernel core/functor core/arrow core The highlighted type classes ar e the first ones you should learn. They’r e well documented and well-known so it’ s easy to get help. a |+ | b a === b a =!= b a |@ | b a *> b a <* b a <+> b a >>> b a <<< b a > b a >= b a < b a <= b Sync Async Ef fect LiftIO ef fect Some type classes intr oduce symbolic operators. NonEmptyT raverse InjectK CommutativeArrow CommutativeFlatMap CommutativeMonad ApplicativeLayer FunctorLayer ApplicativeLayerFunctor FunctorLayerFunctor ApplicativeLocal FunctorEmpty FunctorListen FunctorT ell FunctorRaise MonadLayer MonadLayerFunctor MonadLayerControl MonadState T raverseEmpty Functor Applicative Monad T raverse mtl MTL type classes do not extend cor e type classes dir ectly , but the effect is similar; the dashed line can be r ead “implies”. • Validation • Xor (right-biased Either) • Arrows • Free monad • State monad • Reader/Writer • Monad transformers • ... Used by other libs • Cats-effect • IO ops • Doobie • DB access • FS2 • Streams • http4s Credit to tpolecat for the image from:https://github.com/tpolecat/cats-infographic/
  11. Why all the fuss ? • Build small pieces –

    ideally pure functions • Define algebras • Build for composition • Typed lang => strength • Types – parametrisation • Get high reuse
  12. How and where to start ? • Books about haskell

    • Scala books – Funcional programming in Scala (the red book) – Functional and reactive domain modelling • Hearding the cats – blog series • Scalaz • It does not come by itself. Learning FP requires searching the path (MHO)
  13. Q&A