这是一个依赖类型的lambda演算的语法。
data TermI a = Var a
| App (TermI a) (TermC a) -- when type-checking an application, infer the type of the function and then check that its argument matches the domain
| Star -- the type of types
| Pi (Type a) (Scope () Type a) -- The range of a pi-type is allowed to refer to the argument's value
| Ann (TermC a) (Type a) -- embed a checkable term by declaring its type
deriving (Functor, Foldable, Traversable)
data TermC a = Inf (TermI a) -- embed an inferrable term
| Lam (Scope () TermC a)
deriving (Functor, Foldable, Traversable)
type Type = TermC -- types are values in a dependent type system
(我或多或少地从Simply Easy解除了这个。)类型系统是bidirectional,将术语拆分为可以从打字上下文推断出类型的术语,以及那些只能是检查目标类型。这在依赖类型系统中很有用,因为通常lambda术语没有主体类型。
无论如何,我一直试图为这种语法定义一个Monad
实例:
instance Monad TermI where
return = Var
Var x >>= f = f x
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 >>= _)
要填充TermC
实例最后一行的漏洞,我需要a -> TermI b
类型的内容,但f
的类型为a -> TermC b
。我无法使用TermC
构造函数将生成的TermI
嵌入Ann
,因为我不知道TermC
的类型。
此数据类型与bound
的型号不兼容吗?或者是否有一个技巧可以用来使Monad
实例去?
答案 0 :(得分:2)
这根本不可能:TermC
不是monad。替代使用术语来代替变量。为了使其有意义,术语需要能够适合,即足够相似,以使得所得的术语仍具有良好的性质。这意味着它的类型必须是可推断的。 TermC
不会这样做。
您可以实施:
substI :: TermI a -> (a -> TermI b) -> TermI b
substC :: TermC a -> (a -> TermI b) -> TermC b
并且
instance Monad TermI where
return = Var
bind = substI