GADT's - applications and usefulness?

被刻印的时光 ゝ 提交于 2019-12-03 22:14:12

Glambda

Richard Eisenberg makes a very compelling case for GADTs in glambda a simply typed lambda calculus interpreter which uses GADTs to make sure ill-typed programs simply cannot be constructed. Phil Wadler has something similar and simpler here, from which the following sample was taken

data Exp e a where
  Con :: Int -> Exp e Int
  Add :: Exp e Int -> Exp e Int -> Exp e Int
  Var :: Var e a -> Exp e a
  Abs :: Typ a -> Exp (e,a) b -> Exp e (a -> b)
  App :: Exp e (a -> b) -> Exp e a -> Exp e b

The idea is that the type of the expression (in the interpreter) is encoded in the type of the expression as represented in the Haskell program.

Vectors typed according to their lengths

By using GADTs, we can add a phantom type that tells us keeps track of the length of the vector we have. This package has a nice implementation. This can be reimplemented in a bunch of ways (for example using GHC.TypeLits type-level natural numbers). The interesting data type (copied from the source of the package linked) is

data Vector (a :: *) (n :: Nat)  where
  Nil  :: Vector a Z
  (:-) :: a -> Vector a n -> Vector a (S n)

Then, I can write a safe version of head' :: Vector a (S n) -> a.

Constraints

I don't have a good example demonstrating the usefulness of this, but you can tack on constraints to individual constructors in the GADT. The constraints you add on the constructors are enforced when you construct something and are available when you pattern match. This lets us do all sorts of fun stuff.

data MyGADT b where
  SomeShowable :: Show a => a -> b -> MyGADT b     -- existential types!
  AMonad :: Monad b => b -> MyGADT b
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!