na: Applicative[N]): Applicative[({type λ[α]=M[N[α]]})#λ] = new Applicative[({type λ[α]=M[N[α]]})#λ] { def ap[A, B](f: M[N[A => B]], a: M[N[A]]) = { def liftA2[X, Y, Z](f: X => Y => Z, a: M[X], b: M[Y]): M[Z] = ma.ap(ma.fmap(f, a), b) liftA2((ff: N[A => B]) => (aa: N[A]) => na.ap(ff, aa), f, a) } def point[A](a: A) = ma point (na point a) }
f of A x B such that for all a ∈ A exists exactly one b ∈ B such that (a, b) ∈ f If A are Integers and B are Strings: f(42) -> "puppy" ✅ f(43) -> "kitten" ✅ f(42) -> "shark" ⛔ ! 42 is mapped to two values !
+ 1 val x = inc(42) An expression is REFERENTIALLY TRANSPARENT if this ALWAYS holds true: inc(42) == 43 So: val x = 43 // 43 or inc(42) doesn't make a difference
mutable collections import scala.collection.mutable.ListBuffer val list = ListBuffer(1, 2, 3) list.append(4) println(list) // ListBuffer(1, 2, 3, 4) // mutable values case class User(name: String, var age: Int) val gab = User("Gabriele", 27) gab.age = 10 // I'm a kid again!
that can grow. I need to plan ways in which it might grow. But I need, too, to leave some choices so that other persons can make those choices at a later time” Growing a Language, by Guy Steele
class Reindeer(bells: Int) extends Animal animal match { case Dog(Some(owner)) => // handle dogs with owners case Dog(None) => // handle stray dogs case Reindeer(bells) if bells > 4 => // handle reindeers with more than 4 bells }
doSomethingElse(x, y, context) can we avoid passing context around? implicit val context = // some context def doSomething(a: Int, b: Int)(implicit context: Context) doSomething(a, b) // Black magic!
around) we now have libraries like: » scalaz/cats: category theory applied to Scala » shapeless: generic programming in Scala Those are CRAZY projects, that no-one could envision when designing the language