Polymorphism and Decoupling.
- Parametric
List of
Int
, list ofDouble
, types are as type parameters in a context(List
), not as types of direct values(without context) which infer the idea of ad-hoc polymorphism
- Ad-hoc polymorphism
Typeclass addresses the problems that ad-hoc polymorphism where your operations want to potentially do something different for the different types of values that it accepts. Typeclass aim to decouple ad hoc polymorphism
The method name, which represent as behaviour, not required to be the same. This is a very weak link to the concept of type polymorphism.
a.k.a typecasing.
In order to load the typeclass automatically, inject the type class instance(implicit object implements that type class) as implicit parameter.
implicit def ListIsSerializable[T](implicit ev: Serializable[T]) = ....
// shorthand to
implicit def ListIsSerializable[T : Serializable] =
new Serializable[List[T]] {
def ser(xs: List[T]) = xs.map(serialize(_)).mkString("List(",",",")")
}
serialize(List(Person("Seth", 1), Person("Some", 2)))
// String = List(Person(Seth, 1), Person(Some, 2))
implicit def addSerializable[T](n: T)(implicit s: Serializable[T]) =
new { def serialize = s.sert(n) }
The new
keyword without class name, is as creating an object of anonymous class.
http://stackoverflow.com/questions/9727637/new-keyword-in-scala
You might have implicit parameters defined same return type repeatedly. Though the ambiguity would happened when we not explicitly supplied which implicit parameter we use. We can pass that implicit parameter as higher order function's last input to resolve this issue:
case class SomeClass() {
def shouldBeHigherOrder(v: Int)(implicit x: Z) = ....
}
implicit val z1 = Z.map(_.anotherZ)
implicit val z2 = Z.map(_.someZ)
instanceOfSomeClass.shouldBeHigherOrder(5)
// ambiguous implicit values
instanceOfSomeClass.shouldBeHigherOrder(5)(z1)
// imp. with _.anotherZ
instanceOfSomeClass.shouldBeHigherOrder(5)(z2)
// imp. with _.someZ
It should be a good practice that putting implicit parameters to higher order function's last input.
Type class works at compile time only. Others are at run time.
So if the type information lost, compiler will try to find the most reasonable type def. for it, unfortunatelly it should be Any
type in most cases.
Performance penalties occurred because of adding extra layer of method call.
https://www.quora.com/What-does-it-mean-if-a-language-is-type-safe
"Type safe" usually refers to languages that ensure that an operation is working on the right kind of data at some point before the operation is actually performed. This may be at compile time or at run time.
This is mainly in contrast to languages that are not "type safe", what you might call "type unsafe" languages. In assembler and C you can often treat a pointer as an integer, an integer as a string, a 2-byte integer as a 4-byte integer, or series of bytes as a structure.