About me: @folone likes types*
*same reasons why @propensive does in his “Batshit crazy algebra with types” talk
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
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
> 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
case class Residue[N <: Int: SingleInhabitant](n: Long){
lhs =>
def +(rhs: Residue[N]): Residue[N] =
Residue((lhs.n + rhs.n) % inhabitant[N])
}
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)
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))
}
}
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
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!
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!"
^
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
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
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
State of deptypes Scala “Scala vs Idris: Dependent
Types, Now and in the Future”*
*Edwin Brady & Miles Sabin, Strange Loop 2013
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)
val magic: ((x: Int) => x > 23 && x < 42).type = 30
val x: 42 = 42 val x: ((x: Int) => x == 42).type = 42
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
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:
Top Related