Skip to content

Instantly share code, notes, and snippets.

@Yord
Last active October 30, 2018 05:54
Show Gist options
  • Save Yord/10d19f3a72c9f165e98ff54bdb058b89 to your computer and use it in GitHub Desktop.
Save Yord/10d19f3a72c9f165e98ff54bdb058b89 to your computer and use it in GitHub Desktop.
This gist showcases dotty's implicit functions
// Paste e.g. in https://scastie.scala-lang.org
object Foo {
def main(args: Array[String]): Unit = {
def some[A](a: A): Option[A] = Some(a)
val inc: Int => Int = _ + 1
println(
map(inc)(List(1, 2, 3, 4))
)
println(
map(inc)(some(3))
)
println(
empty[Int]
)
println(
fold((b, a) => b + a.toString)("4")(List(2))
)
println(
fold((b: Int, a: Int) => b + a)(4)(List(2))
)
println(
sum(List(1, 2, 3))
)
println(
sum(List("1", "2", "3"))
)
}
type Map[A, B, F[_]] = (A => B) => F[A] => F[B]
implicit def mapList[A, B]: Map[A, B, List] = f => l => l.map(f)
implicit def mapOption[A, B]: Map[A, B, Option] = f => o => o.map(f)
type Empty[A] = A
implicit def emptyInt: Empty[Int] = 0
implicit def emptyString: Empty[String] = ""
type Combine[A] = (A, A) => A
implicit def combineInt: Combine[Int] = (n, m) => n + m
implicit def combineString: Combine[String] = (n, m) => n + m
type Fold[A, B, F[_]] = ((B, A) => B) => B => F[A] => B
implicit def foldList[A, B]: Fold[A, B, List] = f => b => fa => fa.foldLeft(b)(f)
def combine[A](a1: A, a2: A): implicit Combine[A] => A = { implicit combine =>
combine(a1, a2)
}
def empty[A]: implicit Empty[A] => A = { implicit empty =>
empty
}
def fold[A, B, F[_]](f: (B, A) => B)(b: B)(fa: F[A]): implicit Fold[A, B, F] => B = { implicit fold =>
fold(f)(b)(fa)
}
def map[A, B, F[_]](f: A => B)(fa: F[A]): implicit Map[A, B, F] => F[B] = { implicit map =>
map(f)(fa)
}
def sum[A, F[_]](fa: F[A]): implicit (Fold[A, A, F], Combine[A], Empty[A]) => A = { implicit (fold, combine, empty) =>
fold(combine)(empty)(fa)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment