Can someone explain dependent typing to me? I have little experience in Haskell, Cayenne, Epigram, or other functional languages, so the simpler of terms you can use, the m
Dependent types enable larger set of logic errors to be eliminated at compile time. To illustrate this consider the following specification on function f:
Function
fmust take only even integers as input.
Without dependent types you might do something like this:
def f(n: Integer) := {
if n mod 2 != 0 then
throw RuntimeException
else
// do something with n
}
Here the compiler cannot detect if n is indeed even, that is, from the compiler's perspective the following expression is ok:
f(1) // compiles OK despite being a logic error!
This program would run and then throw exception at runtime, that is, your program has a logic error.
Now, dependent types enable you to be much more expressive and would enable you to write something like this:
def f(n: {n: Integer | n mod 2 == 0}) := {
// do something with n
}
Here n is of dependent type {n: Integer | n mod 2 == 0}. It might help to read this out loud as
nis a member of a set of integers such that each integer is divisible by 2.
In this case the compiler would detect at compile time a logic error where you have passed an odd number to f and would prevent the program to be executed in the first place:
f(1) // compiler error
Here is an illustrative example using Scala path-dependent types of how we might attempt implementing function f satisfying such a requirement:
case class Integer(v: Int) {
object IsEven { require(v % 2 == 0) }
object IsOdd { require(v % 2 != 0) }
}
def f(n: Integer)(implicit proof: n.IsEven.type) = {
// do something with n safe in the knowledge it is even
}
val `42` = Integer(42)
implicit val proof42IsEven = `42`.IsEven
val `1` = Integer(1)
implicit val proof1IsOdd = `1`.IsOdd
f(`42`) // OK
f(`1`) // compile-time error
The key is to notice how value n appears in the type of value proof namely n.IsEven.type:
def f(n: Integer)(implicit proof: n.IsEven.type)
^ ^
| |
value value
We say type n.IsEven.type depends on the value n hence the term dependent-types.