Download - Demystifying Scala Type System
![Page 1: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/1.jpg)
David GalichetCTO @ CoachClub
Demystifying Scala Type System
jeudi 29 novembre 12
![Page 2: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/2.jpg)
Schedule
Scala Types 101
Types Variance and Type bounds
Abstract Type members
Ad-Hoc Polymorphism
Existential Types
Generalized Type Constraints
jeudi 29 novembre 12
![Page 3: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/3.jpg)
What is a type system ?
“A type system is a tractable syntactic method for proving the absence of certain program behaviors by classifying phrases according to the kinds of values they compute.“ – Benjamin Pierce
jeudi 29 novembre 12
![Page 4: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/4.jpg)
What is a type ?
A Type defines a set of values a variable can posses and a set of functions that can be applied to these values
Set of values can be defined as
Cartesian product Types (like case classes or Tuples)
Sum Types (like Either)
Types can be Abstract and/or Polymorph
jeudi 29 novembre 12
![Page 5: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/5.jpg)
What is a type ?
In Functional Languages like Scala, a Function is also a Type that can be assigned to a variable or (higher order) function or returned by a (higher order) function
jeudi 29 novembre 12
![Page 6: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/6.jpg)
Why typing ?“Make illegal states unrepresentable“ - Yaron Minsky
“Where static typing fits, do it every time because it has just fantastic maintenance benefits.” - Simon Peyton Jones
Compiler can use Type informations to optimize compiled code
jeudi 29 novembre 12
![Page 7: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/7.jpg)
Scala Types 101
Scala is Object Oriented and Functional
Scala has a strong and static Type SystemTypes are checked at compile time
Types can be inferred by the compiler
Functions are Types : A => B
jeudi 29 novembre 12
![Page 8: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/8.jpg)
Scala Types 101
Types are used to define
[abstract] classes
objects
traits
jeudi 29 novembre 12
![Page 9: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/9.jpg)
Scala Types 101Scala types hierarchy
Enclosed by : Top type ⟙ (Any)
Bottom type ⟘ (Nothing)
Java Primitive Types are wrapped under AnyVal (Unit, Long, Double, Boolean ...)
Since 2.10, you can define your own AnyVal
Any⟙
AnyRefAnyVal
Primitive Types wrappers All Types
Nothing ⟘
jeudi 29 novembre 12
![Page 10: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/10.jpg)
Scala Types 101
Scala Types can be parameterizedList[A]
Either[A, B]
Functions can also take type parameters
def show[A](a:A):String = a.toString
jeudi 29 novembre 12
![Page 11: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/11.jpg)
Type Variance and Bounds
Type Variance goal is to define inheritance relation
By default, Type Parameters are invariant
They can also be defined as co-variant or contra-variant
jeudi 29 novembre 12
![Page 12: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/12.jpg)
Type Variance and Bounds
Co-Variance(M[+T])
if A extends B then M[A] extends M[B]
Contra-Variance (M[-T])
if A extends B then M[B] extends M[A]
B
A
⇒M[B]
M[A]
B
A
⇒M[A]
M[B]
jeudi 29 novembre 12
![Page 13: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/13.jpg)
Type Variance and Bounds
Some examples of Types with varying type parametersList[+A]
Writer[-A]
Function1[-T, +R]
jeudi 29 novembre 12
![Page 14: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/14.jpg)
Type Variance and Bounds
scala> class Test[+A] { | def test(a: A): String = a.toString | }<console>:8: error: covariant type A occurs in contravariant position in type A of value a
WTF ?
jeudi 29 novembre 12
![Page 15: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/15.jpg)
Type Variance and BoundsFirst of all, take a look at Functions :
Function1[-T,+R]
Functions are Co-Variant on return type (+R) and Contra-Variant on parameters (-T) !
We can substitute Function1[A,D] by Function1[B,C] : B Function1[A, D]
C
D
A Function1[B, C]
⋀ ⇒
jeudi 29 novembre 12
![Page 16: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/16.jpg)
Type Variance and Bounds
Type A should be either Invariant or Contra-Variant but it’s Co-Variant
class Test[+A] { def test(a: A): String = a.toString}
This is a Function1 instance !
jeudi 29 novembre 12
![Page 17: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/17.jpg)
Type Variance and Bounds
Solution : introduce a bounded Type
class Test[+A] { def test[B >: A](b: B): String = b.toString}
Lower Type Bound : this new Type B is a super Type of A
Method test will accept A or any super Type of A
jeudi 29 novembre 12
![Page 18: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/18.jpg)
Type Variance and BoundsImplementation of a List
Inherit from any List[T]
trait List[+T] { def ::[U >: T](u: U): List[U] = Cons(u, this)}case class Cons[T](head: T, tail: List[T]) extends List[T]
case object Nil extends List[Nothing]
jeudi 29 novembre 12
![Page 19: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/19.jpg)
Type Variance and Bounds
Variance is not applicable to mutable state :
trait Mutable[+T] { var t: T // generate a setter:
// def t_=(t: T) {this.t = t}}
Co-Variant parameter in Contra-Variant position
⇒ A mutable List can’t be Co-Variant !
jeudi 29 novembre 12
![Page 20: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/20.jpg)
Type Variance and BoundsImplementation of a Writer - Part1
class B { def toString = "I’m B" }class A extends B { def toString = "I’m A" }
trait Writer[-T] { def write(t: T): String }
val bWriter = new Writer[B] { def write(b: B): String = b.toString }
def write[T](t: T)(w: Writer[T]) = w.write(t)
Inherit from any List[T]
jeudi 29 novembre 12
![Page 21: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/21.jpg)
Type Variance and BoundsImplementation of a Writer - Part2
B Write[A]
A Write[B]
⇒
write(new B)(bWriter)res> String = I’m B
write(new A)(bWriter)res> String = I’m A
We need a Writer[A]
Fortunately, Writer[B] extends Writer[A]:
jeudi 29 novembre 12
![Page 22: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/22.jpg)
Type memberConcrete Types can be defined in a class, trait or object
type Color = String // type Aliastype Valid[X] = Either[Throwable, X] // Valid is parametrized with X
We can define these types with their kind :
Color or String has kind *
Valid or Option has kind * ➞ *
Either has kind * ➞ * ➞ *
jeudi 29 novembre 12
![Page 23: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/23.jpg)
Abstract Type membersWe can define Abstract Type in abstract classes or traits
Abstract Types are another way to parameterize Typestrait Foodclass Grass extends Foodclass Fish extends Food
trait Species { type SuitableFood <: Food}
trait Animal extends Species
class Cow extends Animal { type SuitableFood = Grass}
jeudi 29 novembre 12
![Page 24: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/24.jpg)
Abstract Type membersThe parameterized type way :
trait Foodclass Grass extends Foodclass Fish extends Food
trait Species[T <: Food]trait Animal[T <: Food] extends Species[T]
class Cow extends Animal[Grass]
jeudi 29 novembre 12
![Page 25: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/25.jpg)
Ad-Hoc Polymorphism
Ad-Hoc polymorphism is a way to add behavior to an existing class without modifying it
In Haskell, polymorphism is achieved using typeclasses
abs :: (Num a, Ord a) => a -> aabs x = if x < 0 then -x else x
Typeclasses
jeudi 29 novembre 12
![Page 26: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/26.jpg)
Ad-Hoc Polymorphism
In Scala, we can achieve Ad-Hoc polymorphism using implicits
implicits are used in two places
implicit conversion to convert a type to another
implicit parameter
jeudi 29 novembre 12
![Page 27: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/27.jpg)
Ad-Hoc PolymorphismIn Scala, we can achieve Ad-Hoc polymorphism using implicits
Scala library defines many Typeclasses to achieve Ad-Hoc polymorphism : Integral, Numeric, Ordering ...
def abs[T](x: T)(implicit num: Numeric[T]): T = if(num.lt(x, num.zero)) num.negate(x) else x
def max[T: Ordering](x: T, y: T): T = implicitly[Ordering[T]].max(x, y)
jeudi 29 novembre 12
![Page 28: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/28.jpg)
Ad-Hoc PolymorphismWe can define our own instances of existing typeclasses
case class Student(name: String, score: Float)
implicit object StudentOrdering extends Ordering[Student] { def compare(x: Student, y: Student) = x.score.compareTo(y.score)}
scala> max(Student("Bob", 5.6F), Student("Alice", 5.8F))res0: Student = Student(Alice,5.8)
jeudi 29 novembre 12
![Page 29: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/29.jpg)
Ad-Hoc PolymorphismWe can define our own instances of typeclasses
implicit class Printable[A](a: A) { // since Scala 2.10 def printOut(): Unit = println(a.toString)}
scala> "test".printOuttest
jeudi 29 novembre 12
![Page 30: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/30.jpg)
Ad-Hoc PolymorphismA more concrete example - Part 1
trait Searchable[T] { val id: String val indexedContent: String }
class SearchEngine[T](defaultBuilder: String => T){ def index(searchable: Searchable[T]) { /* ... */ } def search(query: String)(builder: String => T = defaultBuilder): T = builder("0")}
jeudi 29 novembre 12
![Page 31: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/31.jpg)
Ad-Hoc Polymorphism
case class Person(id: Long, name: String)
implicit def person2Searchable(p: Person) = new Searchable[Person] { val id = p.id.toString val indexedContent = p.name }
val fakeEngine = new SearchEngine[Person]( id => Person(id.toLong, "retrieved content") )
A more concrete example - Part 2
jeudi 29 novembre 12
![Page 32: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/32.jpg)
Ad-Hoc PolymorphismPolymorphic Typeclasses instance definition
class Hour[X] private (val x: X) { /* ... */ }
object Hour { def apply[X](x: X)(implicit int: Integral[X]):Hour[X]= new Hour(int.rem(int.plus(int.rem(x, int.fromInt(12)), int.fromInt(12)), int.fromInt(12)))}
implicit def hour2Monoid[X](implicit int: Integral[X]): Monoid[Hour[X]] = new Monoid[Hour[X]] { def append(f1: Hour[X], f2: => Hour[X]) = Hour(int.rem(int.plus(f1.x, f2.x), int.fromInt(12))) def zero = Hour(int.zero)}
jeudi 29 novembre 12
![Page 33: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/33.jpg)
Existential Types
Existential types are reference to type parameter that is unknown
The Scala existential type in M[_] is the dual of Java wildcard M<?>
They can be defined using : M[T] forSome { type T }
or M[_]
jeudi 29 novembre 12
![Page 34: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/34.jpg)
Existential Types
We can bound existential types :M[T] forSome { type T <: AnyRef }
or M[_ <: AnyRef]
jeudi 29 novembre 12
![Page 35: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/35.jpg)
Generalized Type ConstraintsConstrain type using an implicit
=:= same type
<:< lower type
>:> super type
jeudi 29 novembre 12
![Page 36: Demystifying Scala Type System](https://reader036.vdocuments.us/reader036/viewer/2022062703/554f9e13b4c9057b298b472d/html5/thumbnails/36.jpg)
Generalized Type Constraints
trait Foodclass Grass extends Foodclass Fish extends Food
trait Animal[SuitableFood <: Food] { def fish(implicit ev: SuitableFood =:= Fish){ println("I'm fishing") }}
class Cow extends Animal[Grass]class Bear extends Animal[Fish]
Example :
jeudi 29 novembre 12