42.type: literal-based singleton types

39
42.type: Literal-based singleton types in Scala @folone @xeno_by @retronym @adriaanm @extempore2

Upload: george-leontiev

Post on 14-Jun-2015

114 views

Category:

Technology


1 download

DESCRIPTION

Presentation at Scala Workshop 2014: http://lampwww.epfl.ch/~hmiller/scala2014/

TRANSCRIPT

Page 1: 42.type: Literal-based Singleton types

42.type: Literal-based singleton types in Scala

@folone @xeno_by @retronym @adriaanm @extempore2

Page 2: 42.type: Literal-based Singleton types

About me: @folone likes types*

*same reasons why @propensive does in his “Batshit crazy algebra with types” talk

Page 3: 42.type: Literal-based Singleton types
Page 4: 42.type: Literal-based Singleton types

Examples

Page 5: 42.type: Literal-based Singleton types

1. Records

Page 6: 42.type: Literal-based Singleton types

val book = ("author" ->> "Benjamin Pierce") :: ("title" ->> "TAPL") :: ("id" ->> 262162091) :: ("price" ->> 44.11) :: HNil !

scala> book("author") // Note the result type res0: String = Benjamin Pierce !

scala> book("id") // Note the result type res1: Int = 262162091

Page 7: 42.type: Literal-based Singleton types

trait Assoc[K] { type V ; val v: V } defined trait Assoc

!

def mkAssoc[K, V0](k: K,v0: V0): Assoc[k.type] { type V = V0 } = new Assoc[k.type] {type V = V0 ; val v = v0} mkAssoc: [K, V0](k: K, v: V0)Assoc[k.type]{type V = V0}

!

def lookup[K](k: K) (implicit a: Assoc[k.type]): a.V = a.v lookup: [K](k: K)(implicit assoc: Assoc[k.type])assoc.V

Page 8: 42.type: Literal-based Singleton types

> implicit def firstAssoc = mkAssoc(1, "Panda!") firstAssoc: Assoc[1.type]{type V = String}

!

> implicit def ageAssoc = mkAssoc("Age", 3) ageAssoc: Assoc["Age".type]{type V = Int} !> implicit def nmAssoc = mkAssoc(“Name", “Jane”) nmAssoc: Assoc["Name".type]{type V = String}

scala> lookup(1)

res0: String = Panda! scala> lookup("Age")

res1: Int = 3 scala> lookup("Name")

res2: String = Jane

Page 9: 42.type: Literal-based Singleton types

2. Residue

Page 10: 42.type: Literal-based Singleton types

case class Residue[N <: Int: SingleInhabitant](n: Long){

lhs =>

def +(rhs: Residue[N]): Residue[N] =

Residue((lhs.n + rhs.n) % inhabitant[N])

}

Page 11: 42.type: Literal-based Singleton types

scala> Residue[15](15) + Residue[13](20)

<console>:10: error: type mismatch;

found : Residue[13.type]

required: Residue[15.type]

Residue[15](15) + Residue[13](20)

^

scala> Residue[13](15) + Residue[13](20)

res1: Residue[13.type] = Residue(9)

Page 12: 42.type: Literal-based Singleton types

3. Ranged

Page 13: 42.type: Literal-based Singleton types

class Ranged[From <: Int : SingleInhabitant,

To <: Int : SingleInhabitant] {

def sample = {

val rnd = new scala.util.Random

val from = inhabitant[From]

val to = inhabitant[To]

(from + rnd.nextInt(to - from + 1))

}

}

Page 14: 42.type: Literal-based Singleton types

scala> val range = new Ranged[10, 20]

range: Ranged[10.type,20.type] =

Ranged@78c22d25

!

scala> range.sample

res0: Int = 13

!

scala> range.sample

res1: Int = 11

Page 15: 42.type: Literal-based Singleton types

Consistency

Page 16: 42.type: Literal-based Singleton types

Here’s what you can do in Scala

scala> val x = "panda!" x: String = panda! !scala> val t: x.type = x t: x.type = panda! !scala> final val k = "panda!" k: String("panda!") = panda!

Page 17: 42.type: Literal-based Singleton types

Here’s what you cannot

scala> val t: "panda!".type = "panda!"

<console>:1: error: identifier expected

but string literal found.

val t: "panda!".type = "panda!"

^

Page 18: 42.type: Literal-based Singleton types

scala> val t: "panda!".type = "panda!"

t: "panda!".type = panda!

With 42.type

Page 19: 42.type: Literal-based Singleton types

scala> val x = 42 x: Int = 42 !

scala> val t: x.type = 42 <console>:8: error: type mismatch; found : x.type (with underlying type Int) required: AnyRef val t: x.type = 42 ^scala> val workaround = Witness(42) workaround: shapeless.Witness{type T = Int(42)} = fresh$macro$3$1@35b45d3f !scala> val t: workaround.T = 42 t: workaround.T = 42

Even more

Page 20: 42.type: Literal-based Singleton types

scala> val t: 42.type = 42 t: 42.type = 42 !!!scala> val t: 42 = 42 t: 42.type = 42

Or even

Solution with 42.type

Page 21: 42.type: Literal-based Singleton types

42: Literal-based singleton types in Scala

Page 22: 42.type: Literal-based Singleton types

SimpleType ::= Path ‘.’ type

A singleton type is of the form p.type, where p is a path pointing to a value

expected to conform to scala.AnyRef.

Before

Page 23: 42.type: Literal-based Singleton types

After

| Literal [‘.’ type]

SimpleType ::= Path ‘.’ type

Page 24: 42.type: Literal-based Singleton types

4.

Page 25: 42.type: Literal-based Singleton types

State of deptypes Scala “Scala vs Idris: Dependent

Types, Now and in the Future”*

*Edwin Brady & Miles Sabin, Strange Loop 2013

Page 26: 42.type: Literal-based Singleton types

How can we make it better? Well, we can try.

Scala + Z3

Page 27: 42.type: Literal-based Singleton types

scala> import z3.scala._, z3.scala.dsl._

import z3.scala._

import z3.scala.dsl._

Page 28: 42.type: Literal-based Singleton types

scala> findAll((x: Val[Int]) => x > 23 && x < 42).toList

res0: List[Int] = List(24, 25, 26, 27, 28, 29, 30, 31,

32, 33, 34, 35, 36, 37, 38, 39, 40, 41)

Page 29: 42.type: Literal-based Singleton types

((x: Val[Int]) => x > 23 && x < 42)

Page 30: 42.type: Literal-based Singleton types

((x: Int) => x > 23 && x < 42)

Page 31: 42.type: Literal-based Singleton types

((x: Int) => x > 23 && x < 42).type

Page 32: 42.type: Literal-based Singleton types

val magic: ((x: Int) => x > 23 && x < 42).type = 30

Page 33: 42.type: Literal-based Singleton types

val magic: ((x: Int) => x > 23 && x < 42).type = 30

val x: 42 = 42 val x: ((x: Int) => x == 42).type = 42

Page 34: 42.type: Literal-based Singleton types

val x: 42 = 42 val x: ((x: Int) => x == 42).type = 42

val x: Int = 42 val x: ((x: Int) => x).type = 42

val magic: ((x: Int) => x > 23 && x < 42).type = 30

Page 35: 42.type: Literal-based Singleton types
Page 36: 42.type: Literal-based Singleton types

bit.ly/42_type

Page 37: 42.type: Literal-based Singleton types

this thing would not be possible without: @xeno_by, @retronym, @adriaanm,

and initial impl by @paulp Scala Z3 bindings: LARA@EPFL

Z3: Microsoft research slides, illustrations: @killnicole

Credits:

Page 38: 42.type: Literal-based Singleton types
Page 39: 42.type: Literal-based Singleton types

- Contributing to Scala compiler - Type-level programming - Working/hackertime at SoundCloud

Ask me about:

Thanks. Questions?