Here is the syntax for a notoriously typical lambda calculus.
data TermI a = Var a | App (TermI a) (TermC a)
(I more or less removed this from Just easy .) The bidirectional type system , separating the terms into those whose types can be inferred from the input context and those that can only be checked against the target type. This is useful in systems of dependent types, since in general the lambda members will not be of a fundamental type.
Anyway, I'm stuck trying to define a Monad instance for this syntax:
instance Monad TermI where return = Var Var x >>= f = fx App fun arg >>= f = App (fun >>= f) (arg >>= Inf . f) -- embed the substituted TermI into TermC using Inf Star >>= _ = Star Pi domain range >>= f = Pi (domain >>= Inf . f) (range >>>= Inf . f) Ann term ty >>= f = Ann (term >>= Inf . f) (ty >>= Inf . f) instance Monad TermC where return = Inf . return Lam body >>= f = Lam (body >>>= f) Inf term >>= f = Inf (term >>= _)
To fill the hole in the last line of the TermC instance, I need something like a -> TermI b , but f is of type a -> TermC b . I cannot insert the resulting TermC into TermI using the Ann constructor, because I do not know the type of TermC .
Is this data type incompatible with the bound model? Or is there a trick I can use to create an instance of Monad ?
source share