2. List type
Haskell
data List a = Nil | Cons a (List a)
Scala
sealed trait List[+A]
case object Nil extends List[Nothing]
case class Cons[A](head: A, tail: List[A]) extends List[A]
Java
public interface List<A> {}
public class Nil<A> implements List<A> {}
public class Cons<A> implements List<A> {
private final A head;
private final List<A> tail;
}
Dmytro Mitin List type
3. List type
1 Type Formation
Γ A : ∗
Γ List A : ∗
2 Constructors
Γ A : ∗
Γ nil : List A
Γ h : A Γ t : List A
Γ cons h t : List A
3 Eliminator
Γ c1 : C Γ, h : A, t : List A c2 : C
Γ, x : List A caseList(x)(c1, λht.c2) : C
x match { case Nil => c1; case Cons(h, t) => c2(h, t) }
Dmytro Mitin List type
4. List type
4 Computation rules (”β-reduction“)
Γ c1 : C Γ, h : A, t : List A c2 : C
Γ caseList(nil)(c1, λht.c2) ≡ c1 : C
Γ c1 : C Γ, h : A, t : List A c2 : C
Γ h : A Γ t : List A
Γ caseList(cons h t )(c1, λht.c2) ≡ c2[h ← h , t ← t ] : C
5 Uniqueness principle (”η-conversion“)
Dmytro Mitin List type
5. ProvingGround
git clone https://github.com/siddhartha-gadgil/ProvingGround.git
cd ProvingGround
sbt mantle/test:console
import TLImplicits.
import shapeless.
val Nat = "Nat" :: Type
val NatInd = ("0" ::: Nat) |: ("succ" ::: Nat -->>: Nat) =: Nat
val zero :: succ :: HNil = NatInd.intros
val one = succ(zero)
val two = succ(one)
val three = succ(two)
val A = "A" :: Type
val ListA = "List(A)" :: Type
val ListAInd = ("nil" ::: ListA) |: ("cons" ::: A ->>: ListA -->>:
ListA ) =: ListA
val nil :: cons :: HNil = ListAInd.intros
Dmytro Mitin List type
6. ProvingGround
val recLN = ListAInd.rec(Nat)
val a = "a" :: A
val as = "as" :: ListA
val n = "n" :: Nat
val size = recLN(zero)(a :-> (as :-> (n :-> succ(n) )))
val a1 = "a1" :: A
val a2 = "a2" :: A
val list = cons(a)(cons(a1)(cons(a2)(nil)))
size(list) == three
Dmytro Mitin List type