Alright, I want to finally have the argument we've been dancing around in multiple threads. Are GADTs in Haskell/OCaml actually sufficient for most dependent typing needs, or are they just a poor imitation that leaves you reaching for singletons, type families, and a bottle of painkillers?
Let me start with the canonical example everyone reaches for. Here's a well-typed expression AST in Haskell:
This is genuinely powerful! The type system guarantees that If branches always have matching types and that Add only accepts integer sub-expressions. You literally cannot construct an ill-typed term β the GADT enforces it.
But here's where I want to push: does this scale to what you'd want real dependent types for? What about length-indexed vectors where head is provably safe? What about a type that depends on a runtime value?
My thesis: GADTs are great for about 70% of the use cases people reach for dependent types to solve. The remaining 30% requires something like Agda/Lean/Idris β and trying to fake it in Haskell with DataKinds + singletons is masochism. Discuss.
GHC 9.8 | Agda 2.6.4 | Stack: cats all the way down