{-# LANGUAGE GADTs, KindSignatures, MultiParamTypeClasses, FunctionalDependencies #-} -- Program from Josef Svenningsson -- Just a short explanation of the program. It contains -- some class declarations capturing some definitions from -- category theory. Further down he have a data type for well typed -- lambda expressions using GADTs. Finally we have a -- function defining the semantics for lambda terms called -- 'interp'. -- Made GHC 6.4 bleat -- Quantified type variable `t' is unified with -- another quantified type variable `terminal' -- When trying to generalise the type inferred for `interp' module Bug where import Data.Kind (Type) class Category arr where idA :: arr a a comp :: arr a b -> arr b c -> arr a c class Category arr => Terminal terminal arr | arr -> terminal where terminal :: arr a terminal class Category arr => ProductCategory prod arr | arr -> prod where first :: arr (prod a b) a second :: arr (prod a b) b pair :: arr a b -> arr a c -> arr a (prod b c) class Category arr => CoproductCategory coprod arr | arr -> coprod where inLeft :: arr a (coprod a b) inRight :: arr b (coprod a b) ccase :: arr a c -> arr b c -> arr (coprod a b) c class ProductCategory prod arr => Exponential exp prod arr | arr -> exp where eval :: arr (prod (exp a b) a) b curryA :: arr (prod c a) b -> arr c (exp a b) class (Exponential exp prod arr, Terminal terminal arr) => CartesianClosed terminal exp prod arr | arr -> terminal exp prod data V prod env t where Z :: V prod (prod env t) t S :: V prod env t -> V prod (prod env x) t data Lambda terminal (exp :: Type -> Type -> Type) prod env t where Unit :: Lambda foo exp prod env foo Var :: V prod env t -> Lambda terminal exp prod env t {- Lam :: Lambda terminal exp prod (prod env a) t -> Lambda terminal exp prod env (exp a t) App :: Lambda terminal exp prod env (exp t t') -> Lambda terminal exp prod env t -> Lambda terminal exp prod env t' -} interp :: CartesianClosed terminal exp prod arr => Lambda terminal exp prod s t -> arr s t interp (Unit) = terminal -- Terminal terminal arr => arr a terminal -- interp (Var Z) = second -- interp (Var (S v)) = first `comp` interp (Var v) -- interp (Lam e) = curryA (interp e) -- interp (App e1 e2) = pair (interp e1) (interp e2) `comp` eval