Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@fancellu
Last active May 18, 2020 14:05
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fancellu/20a4750031620ebc5bad31189125632c to your computer and use it in GitHub Desktop.
Save fancellu/20a4750031620ebc5bad31189125632c to your computer and use it in GitHub Desktop.
Example usage of Simulacrum Typeclass, v similar to math.Ordering/Numeric in standard SDK
showing Int 25
false
true
showing Boolean true
false
false
true
true
false
false
true
List(false, true, true)
List(showing Int 0, showing Int 2, showing Int 3)
List(, one, three, two)
List(showing String , showing String one, showing String three, showing String two)
import simulacrum._
// Example usage of Simulacrum, v similar to math.Ordering/Numeric in standard SDK
object SimType extends App {
@typeclass trait Showing[T] {
def show(x: T): String
}
@typeclass trait Ordering[T] extends Showing[T]{
def compare(x: T, y: T): Int
@op("<") def lt(x: T, y: T): Boolean = compare(x, y) < 0
@op(">") def gt(x: T, y: T): Boolean = compare(x, y) > 0
}
@typeclass trait Numeric[T] extends Ordering[T] {
@op("+") def plus(x: T, y: T): T
@op("*") def times(x: T, y: T): T
@op("unary_-") def negate(x: T): T
def zero: T
def abs(x: T): T = if (lt(x, zero)) negate(x) else x
}
implicit val NumericInt = new Numeric[Int] {
override def show(x:Int)=s"showing Int $x"
override def plus(x: Int, y: Int): Int = x + y
override def times(x: Int, y: Int): Int = x * y
override def negate(x: Int): Int = -x
override def zero: Int = 0
override def compare(x: Int, y: Int): Int = if (x == y) 0 else if (x < y) -1 else 1
}
import Numeric.ops._
def square[T: Numeric](t: T): T = t * t
println(square((5)).show)
implicit val numericBoolean = new Numeric[Boolean] {
override def show(x:Boolean)=s"showing Boolean $x"
override def plus(x: Boolean, y: Boolean): Boolean = x || y
override def times(x: Boolean, y: Boolean): Boolean = x && y
override def negate(x: Boolean): Boolean = !x
override def zero: Boolean = false
//override def compare(x: Boolean, y: Boolean): Int = if (x==y) 0 else if (!x) -1 else 1
override def compare(x: Boolean, y: Boolean): Int = x.compare(y)
}
println(square((false)))
println(square((true)))
println((-false).show)
println(-true)
println(false + false)
println(false + true)
println(true + true)
println(false * false)
println(false * true)
println(true * true)
// note these only require Ordering/Showing, not Numeric
def sorted[T: Ordering](list: List[T]): List[T] =list.sortWith(Ordering[T].lt)
def sortedShow[T: Ordering](list: List[T]): List[String] =list.sortWith(Ordering[T].lt).map(Showing[T].show)
println(sorted(List(true, true, false)))
println(sortedShow(List(3,2,0)))
// so let's define an ordering for String
implicit val orderingString = new Ordering[String] {
override def show(x:String)=s"showing String $x"
override def compare(x: String, y: String): Int=x.compare(y)
}
val strings=List("one","two","three","")
println(sorted(strings))
println(sortedShow(strings))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment