Contravariance is the Dual of Covariance - Erik Meijer

Contravariance is the Dual of Covariance - Erik Meijer

A846fc46522b396026adcb62e162b7dc?s=128

Joy of Coding

March 07, 2014
Tweet

Transcript

  1. Rx! from first principles emeijer@applied-duality.com

  2. Getters ()=>A

  3. Covariant A <: B
 ()=>A <: ()=>B

  4. Functor val map: (A=>B) =>(()=>A)=>()=>B
 
 map f a =()=>f(a())

  5. “Monad” val flatMap:(()=>A)
 =>(A=>(()=>()=>B))=>(()=>B)
 flatMap a f = ()=>f()(a())()

  6. Side Effects val steveb: ()=>String
 steveb() // “developer” steveb() //

    “blah” steveb() // “Windows 8” steveb() // ☲
  7. Side Effects ()=>Try[A]

  8. Side Effects val sjobs: ()=>String
 sjobs() // “iPhone” sjobs() //

    “iPad” sjobs() // “iCloud” sjobs() // †
  9. Side Effects ()=>Try[Option[A]]

  10. Getter Getter ()=>
 (()=>
 Try[Option[A]]
 )

  11. Interfaces trait Enumerable[+T] {
 def getEnumerator(): Enumerator[T]
 } ! trait

    Enumerator[+T] {
 def moveNext(): Boolean
 def current: T
 }
  12. Lifting trait Enumerable[+T] {
 def getEnumerator(): Enumerator[T] ! def lift(f:

    Enumerator[T]=>Enumerator[S]):
 val that = this Enumerable[S] = {
 new Enumerable[S] {
 def getEnumerator() = f(that.GetEnumerator()) }
 }
 }
  13. Functor val map: (A=>B)=>
 Enumerable[A]=>Enumerable[B]
 
 map f as =

    as.lift(_.map)
  14. Monad val flatMap: (A=>Enumerable[B])=>
 Enumerable[A]=>Enumerable[B]
 
 flatmap f as =

    as.lift(_.flatmap)
  15. Reverse
 All
 Those =>

  16. Setters A=>()

  17. Contravariant A <: B
 B=>() <: A=>()

  18. coFunctor val map: (A=>B) =>((B=>())=>(A=>()))
 
 map f b =

    a=>(b(f a))
  19. “Monad” val flatMap:(A=>())
 =>(B=>((()=>A)=>())=>(B=>()) flatMap a f = b=>f(b)(a)

  20. Side Effects val emeijer: String=>()
 emeijer(“Comega”) emeijer(“LINQ”) emeijer(“Rx”) emeijer(☲)

  21. Side Effects Try[A]=>()

  22. Side Effects val kubric: String=>()
 kubric(“Spartacus”) kubric(“Lolita”) kubric(“Eyes Wide Shut”)

    kubric(†)
  23. Side Effects Try[Option[A]]=>()

  24. Setter Setter (Try[Option[A]] => ()
 )=>()

  25. Interfaces trait Observable[+T] {
 def Subscribe(o: Observer[T]): Unit
 } !

    trait Observer[-T] {
 def onCompleted(): Unit
 def onError(error: Throwable): Unit
 def onNext(value: T): Unit
 }
  26. Lifting trait Observable[+T] {
 def subscribe(o: Observer[T]) ! def lift(f:

    Observer[S]=>Observer[T]):
 val that = this Observable[S] = {
 new Observable[S] {
 def subscribe(o: Observer[S]) = that.Subscribe(f(o)) }
 }
 }
  27. Functor val map: (A=>B)=>
 Observable[A]=>Observable[B]
 
 map f as =

    as.lift(_.map)
  28. Monad val flatMap:(A=>Observable[B])=>
 Observable[A]=>Observable[B]
 
 flatmap f as = as.lift(_.flatmap)

  29. Real World

  30. Real World

  31. Real World