SlideShare une entreprise Scribd logo
1  sur  91
Télécharger pour lire hors ligne
Scala’s	

Types of Types
bg = game @ http://www.swordandsworcery.com/

Konrad 'ktoso' Malawski	

Lambda Days 2014 @ Kraków
_@

Konrad `@ktosopl` Malawski

geecon.org	

Java.pl / KrakowScala.pl	

sckrk.com / meetup.com/Paper-Cup @ London	

GDGKrakow.pl 	

meetup.com/Lambda-Lounge-Krakow
Types
Types

“Implementation is an implementation detail.”	

~ ktoso
Types in Scala
Types in Scala
Types in Scala
Types are:	

!

static

class Robot!
class Human !
!
val human: Human = new Human!
val roman: Human = new Robot!
!
!
error: type mismatch;!
!
found
: Robot!
!
required: Human!
!
val robot: Human = new Robot!
!

^
Types in Scala
Types are:	

!

static
strong

var two = 2!
two = "two"!
!

error: type mismatch;!
found
: String("two")!
required: Int!
two = "two"!
^
Types in Scala
Types are:	

!

static
strong
inferred
!

val n = 2!
n.getClass.toString == "int"!
!
!
!class Human!
!val p = new Human!

p.getClass.toString == "class Human"
Types in Scala
Types are:	

!
val n: Int = 2

!

static
strong
inferred
annotated after :	


!
!

!
def add(a: Int, b: Int): Int!
Types with Traits
Types with Traits
Traits are:	

!

interfaces
!

implementation:	


trait HasName { !
def name: String!
}!
!
!

class Human extends HasName {!
def name = ""!
}
class Human(val name: String) !
extends HasName!
Types with Traits
Traits are:	

!

interfaces
with implementation
!

trait HasName { def name = "name" }!
!

object Human extends HasName!
!

Human.name == "name"!
Types with Traits
Traits are:	

!

interfaces
with implementation
can be “mixed in”

trait Robot!
trait Humanoid!
trait Lasers!
!

object X extends Robot !
with Humanoid!
with Lasers!
!

Multiple inheritance panic?!
Type linearization

trait Robot extends Lasers!
trait Humanoid!
trait Lasers

object X extends Robot !
with Humanoid!
with Lasers

// type linearization:!
X Robot Humanoid Lasers
// reverse!
X Lasers Humanoid Robot! !
!
// expand!
X Lasers Humanoid Robot Lasers
// right-keep-unique!
X Lasers Humanoid Robot Lasers!
X
Humanoid Robot Lasers
// add common!
X
Humanoid Robot Lasers Object Any
Type linearization

trait Robot extends Lasers!
trait Humanoid!
trait Lasers

object X extends Robot !
with Humanoid!
with Lasers

// don’t trust me, trust the compiler:!
import scala.reflect.runtime.universe._!
typeOf[X.type].baseClasses.map(_.name).mkString(“ extends ")!
!

// output:!
X extends Humanoid !
extends Robot extends Lasers !
extends Object extends Any!
Type linearization
reordered slightly
trait Robot extends Lasers!
trait Humanoid!
trait Lasers

object X extends Humanoid!
with Lasers!
with Robot

// type linearization:!
X Humanoid Lasers Robot
// reverse!
X Robot Lasers Humanoid! !
!
// expand!
X Robot Lasers Lasers Humanoid
// right-keep-unique!
X Robot Lasers Lasers Humanoid!
X Robot
Lasers Humanoid
// add common!
X Robot
Lasers Humanoid Object Any
Type linearization

trait Robot extends Lasers!
trait Humanoid!
trait Lasers

object X extends Humanoid!
with Lasers!
with Robot

// don’t trust me, trust the compiler:!
import scala.reflect.runtime.universe._!
typeOf[X.type].baseClasses.map(_.name).mkString(“ extends ")!
!

// output:!
X extends Robot !
extends Lasers extends Humanoid!
extends Object extends Any!
Type Refinement
Type Refinement
trait Human!
trait Robot

val human: Human = new Human {}!
val roman: Human = new Robot!
Type Refinement
trait Human!
trait Robot

val human: Human = new Human {}!
val roman: Human = new Robot with Human!

plain trait composition
type refinement

Waaah! 	

It’s a robot with human traits!
Compound Types
Compound Types
are	

intersections
of types
!
!
!
!
!

trait
def
}!
trait
def
}!

Openable {!
open()!
Closable {!
close()!
Compound Types
are	

intersections
!

!
!
!
!

open()

trait
def
}!
trait
def
}!

Openable {!
open()!
Closable {!
close()!

close()
Compound Types
are	

intersections
!

trait
def
}!
trait
def
}!

Openable {!
open()!
Closable {!
close()!

!
!
! def openAndClose(it: Openable with Closable) {!
it.open()
!
!

it.close()!
}
Compound Types
are	

intersections
!

trait
def
}!
trait
def
}!

Openable {!
open()!
Closable {!
close()!

!
!
! def openAndClose(it: Openable with Closable) {!
it.open()
!
!

it.close()!
}
Compound Types

this.type

trait
def
}!
trait
def
}!

Openable {!
open(): this.type!
Closable {!
close()!

!
!
!
def openAndClose(it: Openable with Closable) =!
!

it.open().close()
!

Type Parameters
!

Type Parameters	

[Type Variance]
!

Type Parameters	

[Type Variance]	

<: Type Bounds >:
Type Parameters
type constructor

class C[T]
type parameter
Type Variance

class C[T] // in-variant!
class C[+T] // co-variant!
class C[-T] // contra-variant!
Type Bounds (still variance)

class Parent!
class Bottom extends Parent!
!

Type Bounds	

!

Parent >: Bottom
Bottom <: Parent
Parent =:= Parent

// parent is “more” general!
// bottom is “less” general!
// parent is “equal” parent
Type Variance
class C[T]

// in-variant

val x: C[Parent] = new C[Parent]!
!

val x: C[Parent] = new C[Bottom]!
error: type mismatch; found: C[Bottom] required: C[Parent]!
Note: Bottom <: Parent, but class C is invariant in type A.!
You may wish to define A as +A instead. (SLS 4.5)!
!

val x: C[Bottom] = new C[Parent]!
error: type mismatch; found: C[Parent] required: C[Bottom]!
Note: Parent >: Bottom, but class C is invariant in type A.!
You may wish to define A as -A instead. (SLS 4.5)!
Type Variance
class C[+T]

// co-variant

val x: C[Parent] = new C[Parent]!
!

val x: C[Parent] = new C[Bottom]!
!

val x: C[Bottom] = new C[Parent]!
error: type mismatch; found: C[Parent] required: C[Bottom]!
!
!
Type Variance
class C[-T]

// contra-variant

val x: C[Parent] = new C[Parent]!
!

val x: C[Parent] = new C[Bottom]!
error: type mismatch; found: C[Bottom] required: C[Parent]!
!

val x: C[Bottom] = new C[Parent]!
!
!
Structural Type
Structural Types

// a type!
class Closeable {!
def close()!
}

=>

// structural type!
type Closeable = {!
def close()!
}
Structural Types
Kinda’ like “duck typing”

def send(msg: String, box: {def receive(a: String)}) =!
box receive msg

structural type
Structural Types
type alias
type MailBoxLike = { !
def receive(a: String)!
}
def send(msg: String, box: MailboxLike) =!
box receive msg
Structural Types

type MailBoxLike = { !
def receive(a: String)!
}
def send(msg: String, box: MailboxLike) =!
box receive msg
object Home { def receive(a: String) = ??? }!
object Work { def receive(a: String) = ??? }
send("hello at home", Home)!
send("hello at work", Work)
Type Member
Type Member
Same goal as	

Type Parameter
if List was using Type Params
trait StringList!
extends List[String]

=>

trait StringList !
extends List {!
type A = String!
}

if List was using Type Members
Type Member + Type Bound
Same as + / - variance
trait List {!
type A!
}

=>

trait NumbersList extends List {!
type A <: Number!
}

trait IntegerList extends NumbersList {!
type A = Integer!
}
trait FailList extends NumbersList {!
type A = Human // Human is not <: Number!!
}
Type Alias
Without Type Alias
“1st” and “2nd” type param
ALL HOPE IS LOST!
object `bytes -> string` !
extends Builder[Array[Byte], String] {!
!
def make(in: Array[Byte]): String = new String(in)!
}!
Without Type Alias
“1st” and “2nd” type param
Some meaning is lost!
object `bytes -> string` !
extends Builder[Array[Byte], String] {!
!
def make(in: Array[Byte]): String = new String(in)!
}!
Type Alias
From Type Parameter to Type Members

trait Builder[From, To]

=>

trait Builder {!
type From!
type To!
def make(in: From): To!
}
Type Alias

trait Builder { type From; type To; def make(in: From): To }!
trait StringBuilder extends Builder {!
type To = String!
}
trait FromBytesBuilder extends Builder {!
type From = Array[Byte]!
}
object `bytes -> string` extends Builder!
with FromBytesBuilder!
with StringBuilder {!
!
def make(in: From): To = new String(in)!
}!
Type Alias

trait Builder { type From; type To; def make(in: From): To }!

object `bytes -> string` extends Builder {!
type From = Array[Bytes]!
type To = String!
!

def make(in: From): To = new String(in)!
}!
Phantom Types
Phantom Types

Phantom Types are never actually instanciated.

Exactly!

uhm… where are they?
Phantom Types
Marker traits:
sealed trait DoorState!
final class Open
extends DoorState!
final class Closed extends DoorState!
Phantom Types
Marker traits:
sealed trait DoorState!
final class Open
extends DoorState!
final class Closed extends DoorState!

trait Door[State <: DoorState] {!
!

def open[T >: State <: Closed](): Door[Open] !
!
!

def close[T >: State <: Open](): Door[Closed]!
!

}!
!
Phantom Types
Only slide in this talk with implementation!

class Door[State <: DoorState] private () {!
!

def open[T >: State <: Closed]() = !
this.asInstanceOf[Door[Open]]!
!

def close[T >: State <: Open]() =
this.asInstanceOf[Door[Closed]]!

!

}!
!

object Door { def apply() = new Door[Closed] }
Phantom Types
Marker traits:
sealed trait DoorState!
final class Open
extends DoorState!
final class Closed extends DoorState!

class Door[State <: DoorState] private () {!
!

def open[T >: State <: Closed]() = !
this.asInstanceOf[Door[Open]]!
!

def stop[T >: State <: Open]() =
!
this.asInstanceOf[Door[Closed]]!
}!
!

object Door { def apply() = new Door[Closed] }
Phantom Types
Marker traits:
sealed trait DoorState!
final class Open
extends DoorState!
final class Closed extends DoorState!

class Door[State <: DoorState] private () {!
!

def open[T >: State <: Closed]() = !
this.asInstanceOf[Door[Open]]!
!

def stop[T >: State <: Open]() =
!
this.asInstanceOf[Door[Closed]]!
}!
!

object Door { def apply() = new Door[Closed] }
Phantom Types
Marker traits:
sealed trait DoorState!
final class Open
extends DoorState!
final class Closed extends DoorState!

class Door[State <: DoorState] private () {!
!

def open[T >: State <: Closed]() = !
this.asInstanceOf[Door[Open]]!
!

def stop[T >: State <: Open]() =
!
this.asInstanceOf[Door[Closed]]!
}!
!

object Door { def apply() = new Door[Closed] }
Phantom Types
Marker traits:
sealed trait DoorState!
final class Open
extends DoorState!
final class Closed extends DoorState!

class Door[State <: DoorState] private () {!
!

def open[T >: State <: Closed]() = !
this.asInstanceOf[Door[Open]]!
!

def stop[T >: State <: Open]() =
!
this.asInstanceOf[Door[Closed]]!
}!
!

object Door { def apply() = new Door[Closed] }
Phantom Types
val closed = Door()!
// closed: Door[Closed]
Phantom Types
val closed = Door()!
// closed: Door[Closed]!
!

val opened = closed.open()!
// opened: Door[Open]
Phantom Types
val closed = Door()!
// closed: Door[Closed]!
!

val opened = closed.open()!
// opened: Door[Open]!
!

val closedAgain = opened.close()!
// closedAgain: Door[Closed]!
Phantom Types
val closed = Door()!
// closed: Door[Closed]!
!

val opened = closed.open()!
// opened: Door[Open]!
!

val closedAgain = opened.close()!
// closedAgain: Door[Closed]!
!

closed.close()!
error: type arguments [Closed] do not conform to method
close's type parameter bounds [T >: Closed <: Open]
Phantom Types
val closed = Door()!
// closed: Door[Closed]!
!

val opened = closed.open()!
// opened: Door[Open]!
!

val closedAgain = opened.close()!
// closedAgain: Door[Closed]!
!

closed.close()!
error: type arguments [Closed] do not conform to method
close's type parameter bounds [T >: Closed <: Open]!
!

opened.open()!
error: type arguments [Open] do not conform to method !
open's type parameter bounds [T >: Open <: Closed]
Higher Kinded Types
Kind:

x
Proper Kind
Int!

scala> :kind -v 42!
!

scala.Int's kind is A!
*!
!

This is a proper type.
Kind: x -> x
Type Constructor
List[+A]!

scala> :kind -v List!
!

scala.collection.immutable.List's kind is F[+A]!
* -(+)-> *!
!

This is a type constructor: !
a 1st-order-kinded type.
Kind:

(x -> x) -> x
Higher Kind
import language.higherKinds!
!
class Functor[M[_]]!

scala> :kind -v Functor[List]!
!

Functor's kind is X[F[A]]!
(* -> *) -> *!
!

This is a type constructor that takes type constructor(s): !
a higher-kinded type
Higher Kinded Types

import scala.language.higherKinds!
!

takes Type Constructor

trait Functor [F[_]] {!
def map[A,B] (fn: A => B)(fa: F[A]): F[B]!
}
Higher Kinded Types
import scala.language.higherKinds!
!

trait Functor [F[_]] {!
def map[A,B] (fn: A => B)(fa: F[A]): F[B]!
}

trait Functor [List] {!
def map[Int,String] (fn: Int => String)!
(fa: List[Int]): List[String]!
}
Higher Kinded Types
import scala.language.higherKinds!
!

trait Functor [F[_]] {!
def map[A,B] (fn: A => B)(fa: F[A]): F[B]!
}

val funct = new Functor[List] {!
def map[String, Int] !
(f: String => Int)!
(fa: List[String])!
: List[Int] = fa map f // cheating ;-)!
}
Higher Kinded Types
import scala.language.higherKinds!
!

trait Functor [F[_]] {!
def map[A,B] (fn: A => B)(fa: F[A]): F[B]!
}
val funct = new Functor[List] {!
def map[String, Int] !
(f: String => Int)!
(fa: List[String]): List[Int] = !
! ! !!!
fa map f // cheating ;-)!
}
val f: Int => String = _.toString!
funct.map(f)(List(1, 2)) == List("1", "2")!
Power up: Ad-Hoc Polymorphism
trait Container[M[_]] { !
def put[A](x: A): M[A]; def get[A](m: M[A]): A !
}!
implicit val listContainer = new Container[List] { !
def put[A](x: A) = List(x)!
def get[A](m: List[A]) = m.head !
}!
!

implicit val optionContainer = new Container[Some] {!
def put[A](x: A) = Some(x);!
def get[A](m: Some[A]) = m.get !
}!
Power up: Ad-Hoc Polymorphism
trait Container[M[_]] { !
def put[A](x: A): M[A]; def get[A](m: M[A]): A !
}!

def tupleize[M[_]: Container, A, B]!
(fst: M[A], snd: M[B]) !
(implicit c: Container[M]): M[(A, B)] =
c.put(c.get(fst), c.get(snd))
tupleize(Some(1), Some(2))!
Some((1,2)): Some[(Int, Int)]!
!

tupleize(List(1), List(“2”))!
List((1,2)): List[(Int, String)]!
Power up: Ad-Hoc Polymorphism
trait Container[M[_]] { !
def put[A](x: A): M[A]; def get[A](m: M[A]): A !
}!

def tupleize[M[_]: Container, A, B]!
(fst: M[A], snd: M[B]) !
(implicit c: Container[M]): M[(A, B)] =
c.put(c.get(fst), c.get(snd))
tupleize(Some(1), Some(2))!
Some((1,2)): Some[(Int, Int)]!
!

tupleize(List(1), List(“2”))!
List((1,2)): List[(Int, String)]!
Type Class
Type Class	

A.K.A. “ad-hoc polymorphism”
Type Class	

A.K.A. “More pattern, than type”
Type Class	

A.K.A. “Stay in this room”
Type Class	

A.K.A. “Stay in this room”	

Jerzy has an entire talk about them
Type Class

// no type classes yet!
trait Writeable[Out] {!
def write: Out!
}!
!

case class Num(a: Int, b: Int) extends Writeable[Json] {!
def write = Json.toJson(this)!
}!
Type Class
trait Writes[In, Out] {
def write(in: In): Out!
}!
!
!

Separated “what” from “who”

trait Writeable[Self] {
def writeAs[Out]()!
(implicit writes: Writes[Self, Out]): Out =!
! ! ! !
writes write this!
}!
!
!
!
implicit val jsonNum = Writes[Num, Json] {!
! def write(n: Num) = Json.toJson(n)!
!
}!
!

case class Num(a: Int) extends Writeable[Num]
Type Class
trait Writes[In, Out] {
def write(in: In): Out!
}!
!
!

trait Writeable[Self] {
def writeAs[Out]()!
(implicit writes: Writes[Self, Out]): Out =!
! ! ! !
writes write this!
}!

Implicit parameter

!
!
!
implicit val jsonNum = Writes[Num, Json] {!
! def write(n: Num) = Json.toJson(n)!
!
}!
!

Implicit value

case class Num(a: Int) extends Writeable[Num]
Type Class
implicit val jsonNum = Writes[Num, Json] {
def (n1: Num, n2: Num) = n1.a < n1.!
}!
!

case class Num(a: Int) extends Writeable[Num]
Type Class
implicit val jsonNum = Writes[Num, Json] {
def (n1: Num, n2: Num) = n1.a < n1.!
}!
!

case class Num(a: Int) extends Writeable[Num]

you write:
val jsonNum = Num(12).writeAs[Json]()!
Type Class
implicit val jsonNum = Writes[Num, Json] {
def (n1: Num, n2: Num) = n1.a < n1.!
}!
!

case class Num(a: Int) extends Writeable[Num]

you write:
val jsonNum = Num(12).writeAs[Json]()!

compiler does:
val jsonNum = Num(12).writeAs[Json]()(jsonNum)!
Links & Kudos
ktoso/scala-types-of-types @ github

12444 words and growing
Other Types of Types

type annotation	

case class	

type projection 	

unified type system	

value class	

self recursive type	

bottom types	

type class	

type constructor 	

type variance	

universal trait	

specialized type	

traits	

self type annotation	

dynamic type	

type refinements	

phantom type	

existential type	

type alias	

structural type	

type lambda	

abstract type member	

 path dependent type	

 algebraic data type
Links and Kudos
http://docs.scala-lang.org/
!
http://ktoso.github.io/scala-types-of-types/	

!
!
http://blog.echo.sh/post/68636331334/experimenting-with-peano-numbers-on-scalas-type-system-1	

!
http://stackoverflow.com/questions/6246719/what-is-a-higher-kinded-type-in-scala	

!
http://twitter.github.io/scala_school/advanced-types.html	

!
https://github.com/earldouglas/scala-scratchpad/tree/master/type-lambdas	

!
http://www.scala-lang.org/old/node/136	

!
http://eed3si9n.com/learning-scalaz/polymorphism.html	

!
!
!
Dziękuję!
Thank you!
あろがとう!

(guess “type” occurrences)

K.Malawski @ ebay.com
Konrad.Malwski @ geecon.org
t: ktosopl / g: ktoso
blog: project13.pl

Lambda Days 2014 @ Kraków

Contenu connexe

Tendances

Miles Sabin Introduction To Scala For Java Developers
Miles Sabin Introduction To Scala For Java DevelopersMiles Sabin Introduction To Scala For Java Developers
Miles Sabin Introduction To Scala For Java Developers
Skills Matter
 

Tendances (20)

SE 20016 - programming languages landscape.
SE 20016 - programming languages landscape.SE 20016 - programming languages landscape.
SE 20016 - programming languages landscape.
 
07. haskell Membership
07. haskell Membership07. haskell Membership
07. haskell Membership
 
Quick swift tour
Quick swift tourQuick swift tour
Quick swift tour
 
More expressive types for spark with frameless
More expressive types for spark with framelessMore expressive types for spark with frameless
More expressive types for spark with frameless
 
Scala fundamentals
Scala fundamentalsScala fundamentals
Scala fundamentals
 
Practically Functional
Practically FunctionalPractically Functional
Practically Functional
 
Introduction to Swift 2
Introduction to Swift 2Introduction to Swift 2
Introduction to Swift 2
 
JavaScript Data Types
JavaScript Data TypesJavaScript Data Types
JavaScript Data Types
 
Programming in scala - 1
Programming in scala - 1Programming in scala - 1
Programming in scala - 1
 
Working with Cocoa and Objective-C
Working with Cocoa and Objective-CWorking with Cocoa and Objective-C
Working with Cocoa and Objective-C
 
Scala uma poderosa linguagem para a jvm
Scala   uma poderosa linguagem para a jvmScala   uma poderosa linguagem para a jvm
Scala uma poderosa linguagem para a jvm
 
Scala Refactoring for Fun and Profit
Scala Refactoring for Fun and ProfitScala Refactoring for Fun and Profit
Scala Refactoring for Fun and Profit
 
Miles Sabin Introduction To Scala For Java Developers
Miles Sabin Introduction To Scala For Java DevelopersMiles Sabin Introduction To Scala For Java Developers
Miles Sabin Introduction To Scala For Java Developers
 
From android/java to swift (1)
From android/java to swift (1)From android/java to swift (1)
From android/java to swift (1)
 
Scala Intro
Scala IntroScala Intro
Scala Intro
 
Ponies and Unicorns With Scala
Ponies and Unicorns With ScalaPonies and Unicorns With Scala
Ponies and Unicorns With Scala
 
Intermediate JavaScript
Intermediate JavaScriptIntermediate JavaScript
Intermediate JavaScript
 
Csharp_mahesh
Csharp_maheshCsharp_mahesh
Csharp_mahesh
 
Typeclasses
TypeclassesTypeclasses
Typeclasses
 
What can scala puzzlers teach us
What can scala puzzlers teach usWhat can scala puzzlers teach us
What can scala puzzlers teach us
 

En vedette

Real-World Scala Design Patterns
Real-World Scala Design PatternsReal-World Scala Design Patterns
Real-World Scala Design Patterns
NLJUG
 
The Scottish Information Literacy Project
The Scottish Information Literacy ProjectThe Scottish Information Literacy Project
The Scottish Information Literacy Project
guest9f3d11
 
Effective Scala: Programming Patterns
Effective Scala: Programming PatternsEffective Scala: Programming Patterns
Effective Scala: Programming Patterns
Vasil Remeniuk
 
Ebay legacy-code-retreat
Ebay legacy-code-retreatEbay legacy-code-retreat
Ebay legacy-code-retreat
Konrad Malawski
 

En vedette (20)

Real-World Scala Design Patterns
Real-World Scala Design PatternsReal-World Scala Design Patterns
Real-World Scala Design Patterns
 
OOP - Polymorphism
OOP - PolymorphismOOP - Polymorphism
OOP - Polymorphism
 
Artigo igala
Artigo igalaArtigo igala
Artigo igala
 
The Scottish Information Literacy Project
The Scottish Information Literacy ProjectThe Scottish Information Literacy Project
The Scottish Information Literacy Project
 
Functional Programming and Concurrency Patterns in Scala
Functional Programming and Concurrency Patterns in ScalaFunctional Programming and Concurrency Patterns in Scala
Functional Programming and Concurrency Patterns in Scala
 
Effective Scala: Programming Patterns
Effective Scala: Programming PatternsEffective Scala: Programming Patterns
Effective Scala: Programming Patterns
 
Type Parameterization
Type ParameterizationType Parameterization
Type Parameterization
 
Effective Programming In Scala
Effective Programming In ScalaEffective Programming In Scala
Effective Programming In Scala
 
Scala collections
Scala collectionsScala collections
Scala collections
 
Simple Scala DSLs
Simple Scala DSLsSimple Scala DSLs
Simple Scala DSLs
 
So various polymorphism in Scala
So various polymorphism in ScalaSo various polymorphism in Scala
So various polymorphism in Scala
 
Open soucerers - jak zacząć swoją przygodę z open source
Open soucerers - jak zacząć swoją przygodę z open sourceOpen soucerers - jak zacząć swoją przygodę z open source
Open soucerers - jak zacząć swoją przygodę z open source
 
JavaOne 2013: Java 8 - The Good Parts
JavaOne 2013: Java 8 - The Good PartsJavaOne 2013: Java 8 - The Good Parts
JavaOne 2013: Java 8 - The Good Parts
 
The Eff monad, one monad to rule them all
The Eff monad, one monad to rule them allThe Eff monad, one monad to rule them all
The Eff monad, one monad to rule them all
 
Scalding - the not-so-basics @ ScalaDays 2014
Scalding - the not-so-basics @ ScalaDays 2014Scalding - the not-so-basics @ ScalaDays 2014
Scalding - the not-so-basics @ ScalaDays 2014
 
HBase RowKey design for Akka Persistence
HBase RowKey design for Akka PersistenceHBase RowKey design for Akka Persistence
HBase RowKey design for Akka Persistence
 
Need for Async: Hot pursuit for scalable applications
Need for Async: Hot pursuit for scalable applicationsNeed for Async: Hot pursuit for scalable applications
Need for Async: Hot pursuit for scalable applications
 
Scala’s implicits
Scala’s implicitsScala’s implicits
Scala’s implicits
 
Ebay legacy-code-retreat
Ebay legacy-code-retreatEbay legacy-code-retreat
Ebay legacy-code-retreat
 
Scala dsls-dissecting-and-implementing-rogue
Scala dsls-dissecting-and-implementing-rogueScala dsls-dissecting-and-implementing-rogue
Scala dsls-dissecting-and-implementing-rogue
 

Similaire à Scala Types of Types @ Lambda Days

scala reloaded
scala reloadedscala reloaded
scala reloaded
Mac Liaw
 

Similaire à Scala Types of Types @ Lambda Days (20)

RubyConf Portugal 2014 - Why ruby must go!
RubyConf Portugal 2014 - Why ruby must go!RubyConf Portugal 2014 - Why ruby must go!
RubyConf Portugal 2014 - Why ruby must go!
 
MongoDB World 2019: BSON Transpilers: Transpiling from Any Language to Any La...
MongoDB World 2019: BSON Transpilers: Transpiling from Any Language to Any La...MongoDB World 2019: BSON Transpilers: Transpiling from Any Language to Any La...
MongoDB World 2019: BSON Transpilers: Transpiling from Any Language to Any La...
 
Scala Workshop
Scala WorkshopScala Workshop
Scala Workshop
 
42.type: Literal-based Singleton types
42.type: Literal-based Singleton types42.type: Literal-based Singleton types
42.type: Literal-based Singleton types
 
Back to the Future with TypeScript
Back to the Future with TypeScriptBack to the Future with TypeScript
Back to the Future with TypeScript
 
Akka persistence == event sourcing in 30 minutes
Akka persistence == event sourcing in 30 minutesAkka persistence == event sourcing in 30 minutes
Akka persistence == event sourcing in 30 minutes
 
TypeScript: coding JavaScript without the pain
TypeScript: coding JavaScript without the painTypeScript: coding JavaScript without the pain
TypeScript: coding JavaScript without the pain
 
Type Driven Development with TypeScript
Type Driven Development with TypeScriptType Driven Development with TypeScript
Type Driven Development with TypeScript
 
scala reloaded
scala reloadedscala reloaded
scala reloaded
 
Gunosy.go#7 reflect
Gunosy.go#7 reflectGunosy.go#7 reflect
Gunosy.go#7 reflect
 
Inheritance
InheritanceInheritance
Inheritance
 
Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009
 
Intermediate Swift Language by Apple
Intermediate Swift Language by AppleIntermediate Swift Language by Apple
Intermediate Swift Language by Apple
 
JavaScript.pptx
JavaScript.pptxJavaScript.pptx
JavaScript.pptx
 
Java/Scala Lab 2016. Руслан Шевченко: Несколько трюков scala-разработки, приг...
Java/Scala Lab 2016. Руслан Шевченко: Несколько трюков scala-разработки, приг...Java/Scala Lab 2016. Руслан Шевченко: Несколько трюков scala-разработки, приг...
Java/Scala Lab 2016. Руслан Шевченко: Несколько трюков scala-разработки, приг...
 
How would you describe Swift in three words?
How would you describe Swift in three words?How would you describe Swift in three words?
How would you describe Swift in three words?
 
Milano JS Meetup - Gabriele Petronella - Codemotion Milan 2016
Milano JS Meetup -  Gabriele Petronella - Codemotion Milan 2016Milano JS Meetup -  Gabriele Petronella - Codemotion Milan 2016
Milano JS Meetup - Gabriele Petronella - Codemotion Milan 2016
 
C# basics
 C# basics C# basics
C# basics
 
WDB005.1 - JavaScript for Java Developers (Lecture 1)
WDB005.1 - JavaScript for Java Developers (Lecture 1)WDB005.1 - JavaScript for Java Developers (Lecture 1)
WDB005.1 - JavaScript for Java Developers (Lecture 1)
 
Type script - advanced usage and practices
Type script  - advanced usage and practicesType script  - advanced usage and practices
Type script - advanced usage and practices
 

Plus de Konrad Malawski

Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka StreamsFresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Konrad Malawski
 

Plus de Konrad Malawski (20)

Networks and Types - the Future of Akka @ ScalaDays NYC 2018
Networks and Types - the Future of Akka @ ScalaDays NYC 2018Networks and Types - the Future of Akka @ ScalaDays NYC 2018
Networks and Types - the Future of Akka @ ScalaDays NYC 2018
 
Akka Typed (quick talk) - JFokus 2018
Akka Typed (quick talk) - JFokus 2018Akka Typed (quick talk) - JFokus 2018
Akka Typed (quick talk) - JFokus 2018
 
ScalaSwarm 2017 Keynote: Tough this be madness yet theres method in't
ScalaSwarm 2017 Keynote: Tough this be madness yet theres method in'tScalaSwarm 2017 Keynote: Tough this be madness yet theres method in't
ScalaSwarm 2017 Keynote: Tough this be madness yet theres method in't
 
State of Akka 2017 - The best is yet to come
State of Akka 2017 - The best is yet to comeState of Akka 2017 - The best is yet to come
State of Akka 2017 - The best is yet to come
 
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYCBuilding a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
 
Akka-chan's Survival Guide for the Streaming World
Akka-chan's Survival Guide for the Streaming WorldAkka-chan's Survival Guide for the Streaming World
Akka-chan's Survival Guide for the Streaming World
 
Reactive integrations with Akka Streams
Reactive integrations with Akka StreamsReactive integrations with Akka Streams
Reactive integrations with Akka Streams
 
Not Only Streams for Akademia JLabs
Not Only Streams for Akademia JLabsNot Only Streams for Akademia JLabs
Not Only Streams for Akademia JLabs
 
Reactive Streams, j.u.concurrent & Beyond!
Reactive Streams, j.u.concurrent & Beyond!Reactive Streams, j.u.concurrent & Beyond!
Reactive Streams, j.u.concurrent & Beyond!
 
End to End Akka Streams / Reactive Streams - from Business to Socket
End to End Akka Streams / Reactive Streams - from Business to SocketEnd to End Akka Streams / Reactive Streams - from Business to Socket
End to End Akka Streams / Reactive Streams - from Business to Socket
 
The Cloud-natives are RESTless @ JavaOne
The Cloud-natives are RESTless @ JavaOneThe Cloud-natives are RESTless @ JavaOne
The Cloud-natives are RESTless @ JavaOne
 
Akka Streams in Action @ ScalaDays Berlin 2016
Akka Streams in Action @ ScalaDays Berlin 2016Akka Streams in Action @ ScalaDays Berlin 2016
Akka Streams in Action @ ScalaDays Berlin 2016
 
Krakow communities @ 2016
Krakow communities @ 2016Krakow communities @ 2016
Krakow communities @ 2016
 
The things we don't see – stories of Software, Scala and Akka
The things we don't see – stories of Software, Scala and AkkaThe things we don't see – stories of Software, Scala and Akka
The things we don't see – stories of Software, Scala and Akka
 
100th SCKRK Meeting - best software engineering papers of 5 years of SCKRK
100th SCKRK Meeting - best software engineering papers of 5 years of SCKRK100th SCKRK Meeting - best software engineering papers of 5 years of SCKRK
100th SCKRK Meeting - best software engineering papers of 5 years of SCKRK
 
[Japanese] How Reactive Streams and Akka Streams change the JVM Ecosystem @ R...
[Japanese] How Reactive Streams and Akka Streams change the JVM Ecosystem @ R...[Japanese] How Reactive Streams and Akka Streams change the JVM Ecosystem @ R...
[Japanese] How Reactive Streams and Akka Streams change the JVM Ecosystem @ R...
 
Zen of Akka
Zen of AkkaZen of Akka
Zen of Akka
 
How Reactive Streams & Akka Streams change the JVM Ecosystem
How Reactive Streams & Akka Streams change the JVM EcosystemHow Reactive Streams & Akka Streams change the JVM Ecosystem
How Reactive Streams & Akka Streams change the JVM Ecosystem
 
The Need for Async @ ScalaWorld
The Need for Async @ ScalaWorldThe Need for Async @ ScalaWorld
The Need for Async @ ScalaWorld
 
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka StreamsFresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
 

Dernier

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 

Dernier (20)

Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 

Scala Types of Types @ Lambda Days

  • 1. Scala’s Types of Types bg = game @ http://www.swordandsworcery.com/ Konrad 'ktoso' Malawski Lambda Days 2014 @ Kraków
  • 2. _@ Konrad `@ktosopl` Malawski geecon.org Java.pl / KrakowScala.pl sckrk.com / meetup.com/Paper-Cup @ London GDGKrakow.pl meetup.com/Lambda-Lounge-Krakow
  • 4. Types “Implementation is an implementation detail.” ~ ktoso
  • 7. Types in Scala Types are: ! static class Robot! class Human ! ! val human: Human = new Human! val roman: Human = new Robot! ! ! error: type mismatch;! ! found : Robot! ! required: Human! ! val robot: Human = new Robot! ! ^
  • 8. Types in Scala Types are: ! static strong var two = 2! two = "two"! ! error: type mismatch;! found : String("two")! required: Int! two = "two"! ^
  • 9. Types in Scala Types are: ! static strong inferred ! val n = 2! n.getClass.toString == "int"! ! ! !class Human! !val p = new Human! p.getClass.toString == "class Human"
  • 10. Types in Scala Types are: ! val n: Int = 2 ! static strong inferred annotated after : ! ! ! def add(a: Int, b: Int): Int!
  • 12. Types with Traits Traits are: ! interfaces ! implementation: trait HasName { ! def name: String! }! ! ! class Human extends HasName {! def name = ""! } class Human(val name: String) ! extends HasName!
  • 13. Types with Traits Traits are: ! interfaces with implementation ! trait HasName { def name = "name" }! ! object Human extends HasName! ! Human.name == "name"!
  • 14. Types with Traits Traits are: ! interfaces with implementation can be “mixed in” trait Robot! trait Humanoid! trait Lasers! ! object X extends Robot ! with Humanoid! with Lasers! ! Multiple inheritance panic?!
  • 15. Type linearization trait Robot extends Lasers! trait Humanoid! trait Lasers object X extends Robot ! with Humanoid! with Lasers // type linearization:! X Robot Humanoid Lasers // reverse! X Lasers Humanoid Robot! ! ! // expand! X Lasers Humanoid Robot Lasers // right-keep-unique! X Lasers Humanoid Robot Lasers! X Humanoid Robot Lasers // add common! X Humanoid Robot Lasers Object Any
  • 16. Type linearization trait Robot extends Lasers! trait Humanoid! trait Lasers object X extends Robot ! with Humanoid! with Lasers // don’t trust me, trust the compiler:! import scala.reflect.runtime.universe._! typeOf[X.type].baseClasses.map(_.name).mkString(“ extends ")! ! // output:! X extends Humanoid ! extends Robot extends Lasers ! extends Object extends Any!
  • 17. Type linearization reordered slightly trait Robot extends Lasers! trait Humanoid! trait Lasers object X extends Humanoid! with Lasers! with Robot // type linearization:! X Humanoid Lasers Robot // reverse! X Robot Lasers Humanoid! ! ! // expand! X Robot Lasers Lasers Humanoid // right-keep-unique! X Robot Lasers Lasers Humanoid! X Robot Lasers Humanoid // add common! X Robot Lasers Humanoid Object Any
  • 18. Type linearization trait Robot extends Lasers! trait Humanoid! trait Lasers object X extends Humanoid! with Lasers! with Robot // don’t trust me, trust the compiler:! import scala.reflect.runtime.universe._! typeOf[X.type].baseClasses.map(_.name).mkString(“ extends ")! ! // output:! X extends Robot ! extends Lasers extends Humanoid! extends Object extends Any!
  • 20. Type Refinement trait Human! trait Robot val human: Human = new Human {}! val roman: Human = new Robot!
  • 21. Type Refinement trait Human! trait Robot val human: Human = new Human {}! val roman: Human = new Robot with Human! plain trait composition type refinement Waaah! It’s a robot with human traits!
  • 25. Compound Types are intersections ! trait def }! trait def }! Openable {! open()! Closable {! close()! ! ! ! def openAndClose(it: Openable with Closable) {! it.open() ! ! it.close()! }
  • 26. Compound Types are intersections ! trait def }! trait def }! Openable {! open()! Closable {! close()! ! ! ! def openAndClose(it: Openable with Closable) {! it.open() ! ! it.close()! }
  • 27. Compound Types this.type trait def }! trait def }! Openable {! open(): this.type! Closable {! close()! ! ! ! def openAndClose(it: Openable with Closable) =! ! it.open().close()
  • 32. Type Variance class C[T] // in-variant! class C[+T] // co-variant! class C[-T] // contra-variant!
  • 33. Type Bounds (still variance) class Parent! class Bottom extends Parent! ! Type Bounds ! Parent >: Bottom Bottom <: Parent Parent =:= Parent // parent is “more” general! // bottom is “less” general! // parent is “equal” parent
  • 34. Type Variance class C[T] // in-variant val x: C[Parent] = new C[Parent]! ! val x: C[Parent] = new C[Bottom]! error: type mismatch; found: C[Bottom] required: C[Parent]! Note: Bottom <: Parent, but class C is invariant in type A.! You may wish to define A as +A instead. (SLS 4.5)! ! val x: C[Bottom] = new C[Parent]! error: type mismatch; found: C[Parent] required: C[Bottom]! Note: Parent >: Bottom, but class C is invariant in type A.! You may wish to define A as -A instead. (SLS 4.5)!
  • 35. Type Variance class C[+T] // co-variant val x: C[Parent] = new C[Parent]! ! val x: C[Parent] = new C[Bottom]! ! val x: C[Bottom] = new C[Parent]! error: type mismatch; found: C[Parent] required: C[Bottom]! ! !
  • 36. Type Variance class C[-T] // contra-variant val x: C[Parent] = new C[Parent]! ! val x: C[Parent] = new C[Bottom]! error: type mismatch; found: C[Bottom] required: C[Parent]! ! val x: C[Bottom] = new C[Parent]! ! !
  • 38. Structural Types // a type! class Closeable {! def close()! } => // structural type! type Closeable = {! def close()! }
  • 39. Structural Types Kinda’ like “duck typing” def send(msg: String, box: {def receive(a: String)}) =! box receive msg structural type
  • 40. Structural Types type alias type MailBoxLike = { ! def receive(a: String)! } def send(msg: String, box: MailboxLike) =! box receive msg
  • 41. Structural Types type MailBoxLike = { ! def receive(a: String)! } def send(msg: String, box: MailboxLike) =! box receive msg object Home { def receive(a: String) = ??? }! object Work { def receive(a: String) = ??? } send("hello at home", Home)! send("hello at work", Work)
  • 43. Type Member Same goal as Type Parameter if List was using Type Params trait StringList! extends List[String] => trait StringList ! extends List {! type A = String! } if List was using Type Members
  • 44. Type Member + Type Bound Same as + / - variance trait List {! type A! } => trait NumbersList extends List {! type A <: Number! } trait IntegerList extends NumbersList {! type A = Integer! } trait FailList extends NumbersList {! type A = Human // Human is not <: Number!! }
  • 46. Without Type Alias “1st” and “2nd” type param ALL HOPE IS LOST! object `bytes -> string` ! extends Builder[Array[Byte], String] {! ! def make(in: Array[Byte]): String = new String(in)! }!
  • 47. Without Type Alias “1st” and “2nd” type param Some meaning is lost! object `bytes -> string` ! extends Builder[Array[Byte], String] {! ! def make(in: Array[Byte]): String = new String(in)! }!
  • 48. Type Alias From Type Parameter to Type Members trait Builder[From, To] => trait Builder {! type From! type To! def make(in: From): To! }
  • 49. Type Alias trait Builder { type From; type To; def make(in: From): To }! trait StringBuilder extends Builder {! type To = String! } trait FromBytesBuilder extends Builder {! type From = Array[Byte]! } object `bytes -> string` extends Builder! with FromBytesBuilder! with StringBuilder {! ! def make(in: From): To = new String(in)! }!
  • 50. Type Alias trait Builder { type From; type To; def make(in: From): To }! object `bytes -> string` extends Builder {! type From = Array[Bytes]! type To = String! ! def make(in: From): To = new String(in)! }!
  • 52. Phantom Types Phantom Types are never actually instanciated. Exactly! uhm… where are they?
  • 53. Phantom Types Marker traits: sealed trait DoorState! final class Open extends DoorState! final class Closed extends DoorState!
  • 54. Phantom Types Marker traits: sealed trait DoorState! final class Open extends DoorState! final class Closed extends DoorState! trait Door[State <: DoorState] {! ! def open[T >: State <: Closed](): Door[Open] ! ! ! def close[T >: State <: Open](): Door[Closed]! ! }! !
  • 55. Phantom Types Only slide in this talk with implementation! class Door[State <: DoorState] private () {! ! def open[T >: State <: Closed]() = ! this.asInstanceOf[Door[Open]]! ! def close[T >: State <: Open]() = this.asInstanceOf[Door[Closed]]! ! }! ! object Door { def apply() = new Door[Closed] }
  • 56. Phantom Types Marker traits: sealed trait DoorState! final class Open extends DoorState! final class Closed extends DoorState! class Door[State <: DoorState] private () {! ! def open[T >: State <: Closed]() = ! this.asInstanceOf[Door[Open]]! ! def stop[T >: State <: Open]() = ! this.asInstanceOf[Door[Closed]]! }! ! object Door { def apply() = new Door[Closed] }
  • 57. Phantom Types Marker traits: sealed trait DoorState! final class Open extends DoorState! final class Closed extends DoorState! class Door[State <: DoorState] private () {! ! def open[T >: State <: Closed]() = ! this.asInstanceOf[Door[Open]]! ! def stop[T >: State <: Open]() = ! this.asInstanceOf[Door[Closed]]! }! ! object Door { def apply() = new Door[Closed] }
  • 58. Phantom Types Marker traits: sealed trait DoorState! final class Open extends DoorState! final class Closed extends DoorState! class Door[State <: DoorState] private () {! ! def open[T >: State <: Closed]() = ! this.asInstanceOf[Door[Open]]! ! def stop[T >: State <: Open]() = ! this.asInstanceOf[Door[Closed]]! }! ! object Door { def apply() = new Door[Closed] }
  • 59. Phantom Types Marker traits: sealed trait DoorState! final class Open extends DoorState! final class Closed extends DoorState! class Door[State <: DoorState] private () {! ! def open[T >: State <: Closed]() = ! this.asInstanceOf[Door[Open]]! ! def stop[T >: State <: Open]() = ! this.asInstanceOf[Door[Closed]]! }! ! object Door { def apply() = new Door[Closed] }
  • 60. Phantom Types val closed = Door()! // closed: Door[Closed]
  • 61. Phantom Types val closed = Door()! // closed: Door[Closed]! ! val opened = closed.open()! // opened: Door[Open]
  • 62. Phantom Types val closed = Door()! // closed: Door[Closed]! ! val opened = closed.open()! // opened: Door[Open]! ! val closedAgain = opened.close()! // closedAgain: Door[Closed]!
  • 63. Phantom Types val closed = Door()! // closed: Door[Closed]! ! val opened = closed.open()! // opened: Door[Open]! ! val closedAgain = opened.close()! // closedAgain: Door[Closed]! ! closed.close()! error: type arguments [Closed] do not conform to method close's type parameter bounds [T >: Closed <: Open]
  • 64. Phantom Types val closed = Door()! // closed: Door[Closed]! ! val opened = closed.open()! // opened: Door[Open]! ! val closedAgain = opened.close()! // closedAgain: Door[Closed]! ! closed.close()! error: type arguments [Closed] do not conform to method close's type parameter bounds [T >: Closed <: Open]! ! opened.open()! error: type arguments [Open] do not conform to method ! open's type parameter bounds [T >: Open <: Closed]
  • 66. Kind: x Proper Kind Int! scala> :kind -v 42! ! scala.Int's kind is A! *! ! This is a proper type.
  • 67. Kind: x -> x Type Constructor List[+A]! scala> :kind -v List! ! scala.collection.immutable.List's kind is F[+A]! * -(+)-> *! ! This is a type constructor: ! a 1st-order-kinded type.
  • 68. Kind: (x -> x) -> x Higher Kind import language.higherKinds! ! class Functor[M[_]]! scala> :kind -v Functor[List]! ! Functor's kind is X[F[A]]! (* -> *) -> *! ! This is a type constructor that takes type constructor(s): ! a higher-kinded type
  • 69. Higher Kinded Types import scala.language.higherKinds! ! takes Type Constructor trait Functor [F[_]] {! def map[A,B] (fn: A => B)(fa: F[A]): F[B]! }
  • 70. Higher Kinded Types import scala.language.higherKinds! ! trait Functor [F[_]] {! def map[A,B] (fn: A => B)(fa: F[A]): F[B]! } trait Functor [List] {! def map[Int,String] (fn: Int => String)! (fa: List[Int]): List[String]! }
  • 71. Higher Kinded Types import scala.language.higherKinds! ! trait Functor [F[_]] {! def map[A,B] (fn: A => B)(fa: F[A]): F[B]! } val funct = new Functor[List] {! def map[String, Int] ! (f: String => Int)! (fa: List[String])! : List[Int] = fa map f // cheating ;-)! }
  • 72. Higher Kinded Types import scala.language.higherKinds! ! trait Functor [F[_]] {! def map[A,B] (fn: A => B)(fa: F[A]): F[B]! } val funct = new Functor[List] {! def map[String, Int] ! (f: String => Int)! (fa: List[String]): List[Int] = ! ! ! !!! fa map f // cheating ;-)! } val f: Int => String = _.toString! funct.map(f)(List(1, 2)) == List("1", "2")!
  • 73. Power up: Ad-Hoc Polymorphism trait Container[M[_]] { ! def put[A](x: A): M[A]; def get[A](m: M[A]): A ! }! implicit val listContainer = new Container[List] { ! def put[A](x: A) = List(x)! def get[A](m: List[A]) = m.head ! }! ! implicit val optionContainer = new Container[Some] {! def put[A](x: A) = Some(x);! def get[A](m: Some[A]) = m.get ! }!
  • 74. Power up: Ad-Hoc Polymorphism trait Container[M[_]] { ! def put[A](x: A): M[A]; def get[A](m: M[A]): A ! }! def tupleize[M[_]: Container, A, B]! (fst: M[A], snd: M[B]) ! (implicit c: Container[M]): M[(A, B)] = c.put(c.get(fst), c.get(snd)) tupleize(Some(1), Some(2))! Some((1,2)): Some[(Int, Int)]! ! tupleize(List(1), List(“2”))! List((1,2)): List[(Int, String)]!
  • 75. Power up: Ad-Hoc Polymorphism trait Container[M[_]] { ! def put[A](x: A): M[A]; def get[A](m: M[A]): A ! }! def tupleize[M[_]: Container, A, B]! (fst: M[A], snd: M[B]) ! (implicit c: Container[M]): M[(A, B)] = c.put(c.get(fst), c.get(snd)) tupleize(Some(1), Some(2))! Some((1,2)): Some[(Int, Int)]! ! tupleize(List(1), List(“2”))! List((1,2)): List[(Int, String)]!
  • 77. Type Class A.K.A. “ad-hoc polymorphism”
  • 78. Type Class A.K.A. “More pattern, than type”
  • 79. Type Class A.K.A. “Stay in this room”
  • 80. Type Class A.K.A. “Stay in this room” Jerzy has an entire talk about them
  • 81. Type Class // no type classes yet! trait Writeable[Out] {! def write: Out! }! ! case class Num(a: Int, b: Int) extends Writeable[Json] {! def write = Json.toJson(this)! }!
  • 82. Type Class trait Writes[In, Out] { def write(in: In): Out! }! ! ! Separated “what” from “who” trait Writeable[Self] { def writeAs[Out]()! (implicit writes: Writes[Self, Out]): Out =! ! ! ! ! writes write this! }! ! ! ! implicit val jsonNum = Writes[Num, Json] {! ! def write(n: Num) = Json.toJson(n)! ! }! ! case class Num(a: Int) extends Writeable[Num]
  • 83. Type Class trait Writes[In, Out] { def write(in: In): Out! }! ! ! trait Writeable[Self] { def writeAs[Out]()! (implicit writes: Writes[Self, Out]): Out =! ! ! ! ! writes write this! }! Implicit parameter ! ! ! implicit val jsonNum = Writes[Num, Json] {! ! def write(n: Num) = Json.toJson(n)! ! }! ! Implicit value case class Num(a: Int) extends Writeable[Num]
  • 84. Type Class implicit val jsonNum = Writes[Num, Json] { def (n1: Num, n2: Num) = n1.a < n1.! }! ! case class Num(a: Int) extends Writeable[Num]
  • 85. Type Class implicit val jsonNum = Writes[Num, Json] { def (n1: Num, n2: Num) = n1.a < n1.! }! ! case class Num(a: Int) extends Writeable[Num] you write: val jsonNum = Num(12).writeAs[Json]()!
  • 86. Type Class implicit val jsonNum = Writes[Num, Json] { def (n1: Num, n2: Num) = n1.a < n1.! }! ! case class Num(a: Int) extends Writeable[Num] you write: val jsonNum = Num(12).writeAs[Json]()! compiler does: val jsonNum = Num(12).writeAs[Json]()(jsonNum)!
  • 89. Other Types of Types type annotation case class type projection unified type system value class self recursive type bottom types type class type constructor type variance universal trait specialized type traits self type annotation dynamic type type refinements phantom type existential type type alias structural type type lambda abstract type member path dependent type algebraic data type
  • 91. Dziękuję! Thank you! あろがとう! (guess “type” occurrences) K.Malawski @ ebay.com Konrad.Malwski @ geecon.org t: ktosopl / g: ktoso blog: project13.pl Lambda Days 2014 @ Kraków