Skip to content

Instantly share code, notes, and snippets.

@monadplus
Last active June 28, 2019 16:03
Show Gist options
  • Save monadplus/2a0521074dd13c3930d8cec92357bbc3 to your computer and use it in GitHub Desktop.
Save monadplus/2a0521074dd13c3930d8cec92357bbc3 to your computer and use it in GitHub Desktop.
Notes from dailylife.

Variance:

  • Covariant ( return type )
  • Contravariant ( argument type )

Covariant type on contravariant position:

case class Box[+A](value: A) {
  def set(a: A): Box[A] = Box(a)
}

Error:(4, 11) covariant type A occurs in contravariant position in type A of value a
  def set(a: A): Box[A] = Box(a)

Why this should not compile ?

val catBox = new Box[Cat]
val animalBox: Box[Animal] = catBox

val dog = new Dog
animalBox.set(dog) // runtime-error: a box of cats contains a dog!

Benefits of using FT

Principle of least power (you know what your code can and cannot do)

Constraints on FT

def foo[F[_]: Sync] = F.delay(db.read)
// Sync appears everywhere
def bar[F[_]: Sync] = foo.flatMap ...

vs

trait Db[F[_]] {
  def read[A]: F[A]
}
object Db {
  def apply[F[_]](implicit Db: Db[F]): Db[F] = Db
  def create[F[_]: Sync] = new Db[F] { ... }
}

// Sync only appears close to the top level
def bar[F[_]: Db: Monad] = Db[F].read.flatMap ...

String as Seq

scala.String is just an alias for java.lang.String. There's implicit def wrapString(s: String): WrappedString at scala.Predef object that is automatically imported. WrappedString allows treating String as an "efficient" IndexedSeq (subtype of Seq)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment