# List with GADTs

**URL:** https://discuss.ocaml.org/t/list-with-gadts/10104
**Category:** Learning
**Created:** [July 1, 2022, 6:11am UTC](https://discuss.ocaml.org/t/list-with-gadts/10104 "2022-07-01T06:11:01Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![Jazz](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jazz/32/4425_2.png) [@Jazz](https://discuss.ocaml.org/u/Jazz)
#### Post date: [July 1, 2022, 6:11am UTC](https://discuss.ocaml.org/t/list-with-gadts/10104/1 "2022-07-01T06:11:01Z")

</div>

Hi,

I am learning GADTs and found the below snippet at [ocamlgadt](https://sites.google.com/site/ocamlgadt/). I find that using GADTs, OCaml can check if a list passed to a function is empty or not at compile time!

I have an issue with the snippet though - the list is heterogeneous.  
How could i make it homogeneous without breaking `hd` function?

Thanks.

```auto
module GList = struct 
    type zero
    and _ t =
        | [] : zero t
        | ( :: ) : 'a * 'b t -> ('a * 'b) t
    
    let hd : type a. (a * _) t -> a = function (h :: _) -> h ;;   
end ;;

GList.hd (["hello"; 1.1; 1; 'a']: (_ * _) GList.t) ;;
GList.hd ([] : (_ * _) GList.t) ;;

```

---

<div class="post-metadata">

### Author: ![silene](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/silene/32/2707_2.png) [@silene](https://discuss.ocaml.org/u/silene)
#### Post date: [July 1, 2022, 8:18am UTC](https://discuss.ocaml.org/t/list-with-gadts/10104/2 "2022-07-01T08:18:18Z")

</div>

There are lots of different ways to do it. Here is a possibility. It changes the type family `t` so that its first argument is the type of the list elements and the second one is a type-level boolean that indicates whether the list has elements:

```ocaml
type (_, _) t =
    | [] : ('a, float) t
    | ( :: ) : 'a * ('a, 'b) t -> ('a, unit) t

let hd : type a. (a, unit) t -> a = function (h :: _) -> h

```
