メモ'

data Term a = Term a deriving Show

my_zero :: Term Int
my_zero = Term 0

my_succ :: Term Int -> Term Int
my_succ (Term a) = Term (a + 1)

my_iszero :: Term Int -> Term Bool
my_iszero (Term a) = Term (a == 0)

eval :: Term t -> t
eval (Term x) = x

Haskellで、上記におけるevalの返値の型を複数にする(ADTに押し込んで、tagged union/single typeにするとかじゃなく)にはGADTs使うしか無いんでしょとメッセで言われたので、GADTsと全く同じ事をPhantom Typeっぽくやってあげれば良いじゃない。終わり

*Main> eval (my_iszero my_zero )
True
*Main> eval (my_succ my_zero )
1