Skip to content

Instantly share code, notes, and snippets.

@vasnake
Created July 4, 2016 17:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vasnake/e7957b16ca0ee4eaa815e3639751be7c to your computer and use it in GitHub Desktop.
Save vasnake/e7957b16ca0ee4eaa815e3639751be7c to your computer and use it in GitHub Desktop.
Scala Type Classes example
// type classes example
// based on material from SICP 1.3.1 high-order procedures
// inspired by
// The Neophyte's Guide to Scala Part 12: Type Classes
// http://danielwestheide.com/blog/2013/02/06/the-neophytes-guide-to-scala-part-12-type-classes.html
// scala.math.Numeric is a type class
// that define an interface
// abstract numeric increment (can be int, can be double)
def inc[T : Numeric](x: T) = implicitly[Numeric[T]].plus(x, implicitly[Numeric[T]].one)
// one way to access an implicit value
// abstract numeric cube
def cube[T](x: T)(implicit ev: Numeric[T]) = ev.times(x, ev.times(x, x))
// another way to access
// abstract sum for abstract sequence
def sum[T](op: T => T,
a: T,
next: T => T,
b: T)
(implicit ev: Numeric[T]): T = {
if (ev.gt(a, b)) ev.zero
else ev.plus(op(a), sum(op, next(a), next, b))
}
// int
def sumCubes(a: Int, b: Int): Int = sum[Int](cube[Int], a, inc[Int], b)
sumCubes(1, 10) // 3025
def sumIntegers(a: Int, b: Int): Int = sum[Int](identity, a, inc[Int], b)
sumIntegers(1, 10) // 55
// double
def piterm(x: Double): Double = 1.0 / (x * (x + 2))
def pinext(x: Double): Double = x + 4
def piSum(a: Int, b: Int): Double = sum[Double](piterm, a, pinext, b)
piSum(1, 1000) * 8 // 3.139
// or, you can cast int to double and forget about Numeric type class
def alldouble() = {
def cube(x: Double): Double = x * x * x
def inc(n: Double): Double = n + 1
def sum(op: Double => Double,
a: Double,
next: Double => Double,
b: Double): Double = {
if (a > b) 0
else op(a) + sum(op, next(a), next, b)
}
def sumCubes(a: Int, b: Int) = sum(cube, a, inc, b)
println(sumCubes(1, 10)) // 3025.0
def sumIntegers(a: Int, b: Int) = sum(identity, a, inc, b)
println(sumIntegers(1, 10)) // 55.0
def piterm(x: Double): Double = 1.0 / (x * (x + 2))
def pinext(x: Double): Double = x + 4
def piSum(a: Int, b: Int) = sum(piterm, a, pinext, b)
piSum(1, 1000) * 8 // 3.139
}
alldouble()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment