playground/coq/hlist-shallow.v

58 lines
1.3 KiB
Coq

Require Import List.
Import ListNotations.
Fixpoint hlist (l:list Type):Type :=
match l with
| [] => unit
| t::ts => t * (hlist ts)
end.
Definition hd {t:Type} {ts:list Type}
(l:hlist (t::ts)) : t := fst l.
Definition tl {t:Type} {ts:list Type}
(l:hlist (t::ts)) : hlist ts := snd l.
Definition hnil : hlist [] := tt.
Definition hcons {t:Type} {ts:list Type} (a:t)
: hlist ts -> hlist (t::ts) :=
match ts with
| [] => fun _ => (a, tt)
| (x::xs) => fun hl => (a, hl)
end.
Fixpoint append {ts1 ts2:list Type} :
hlist ts1 -> hlist ts2 -> hlist (ts1 ++ ts2) :=
match ts1 with
| [] => fun _ => fun hl2 => hl2
| t::ts => fun hl1 => fun hl2 =>
(*hcons (hd hl1) (append (tl hl1) hl2)*)
(hd hl1, append (tl hl1) hl2)
end.
Example foo0 : hlist [nat:Type] := (2,tt).
Compute hcons 3 foo0.
(*
= (3, (2, tt))
: hlist [nat; nat : Type]
*)
Compute hcons true (hcons 3 foo0).
(*
= (true, (3, (2, tt)))
: hlist [bool; nat; nat : Type]
*)
Example foo1 : hlist [nat:Type; bool:Type] := (2,(true,tt)).
Compute append foo1 foo0.
(*
= (2, (true, (2, tt)))
: hlist ([nat : Type; bool : Type] ++ [nat : Type])
*)
Compute append foo1 (hcons 3 foo0).
(*
= (2, (true, (3, (2, tt))))
: hlist ([nat : Type; bool : Type] ++ [nat; nat : Type])
*)