Module 如何声明一个模块实现了一个接口,使得签名中的一个类型与另一个类型相同?
我正在OCaml中创建单子,需要编写它们,所以我创建了变形金刚。我用身份monad在transformer中实现了常规monad:Module 如何声明一个模块实现了一个接口,使得签名中的一个类型与另一个类型相同?,module,ocaml,functor,Module,Ocaml,Functor,我正在OCaml中创建单子,需要编写它们,所以我创建了变形金刚。我用身份monad在transformer中实现了常规monad: module type MONAD = sig type 'a m val (>>=) : 'a m -> ('a -> 'b m) -> 'b m val return : 'a -> 'a m end module Identity : MONAD = struct type 'a m = 'a let
module type MONAD = sig
type 'a m
val (>>=) : 'a m -> ('a -> 'b m) -> 'b m
val return : 'a -> 'a m
end
module Identity : MONAD = struct
type 'a m = 'a
let (>>=) m f = f m
let return x = x
end
module OptionT (M : MONAD) : MONAD with type 'a m := ('a option) M.m = struct
type 'a m = ('a option) M.m
let (>>=) m f = M.(>>=) m (fun option ->
match option with
| Some x -> f x
| None -> M.return None)
let return x = M.return @@ Some x
end
module Option = OptionT(Identity)
但是,我不能这样做:
open Option
let _ = (Some 1) >>= (fun x -> Some (x + 1))
错误是:
(Some 1)
This expression has type 'a option
but an expression was expected of type 'b option Identity.m
Some (x + 1)
This expression has type 'a option
but an expression was expected of type 'b option Identity.m
如果我试图用module Identity:MONAD和'a m='a
类型修复错误,我会在module Option=OptionT(Identity)
处得到一个错误,指出
The type `m' is required but not provided
现在看来,'a
已经取代了签名中的'a m
做
很好用
我如何告诉编译器模块实现了签名,以便签名中声明的类型与另一个类型相同,同时仍保留签名的原始类型声明
此表达式具有类型“a”选项,但表达式应为类型“b”选项标识。m
事实上,编译器对标识
一无所知,只知道它的签名是MONAD
。(:MONAD
)不仅仅是帮助编译器的东西,它隐藏了有关标识的所有信息,除了它的签名是MONAD
因此,您可以为此添加类型相等
module Identity : MONAD with type 'a m = 'a = ...
它是有效的
此表达式具有类型“a”选项,但表达式应为类型“b”选项标识。m
事实上,编译器对标识
一无所知,只知道它的签名是MONAD
。(:MONAD
)不仅仅是帮助编译器的东西,它隐藏了有关标识的所有信息,除了它的签名是MONAD
因此,您可以为此添加类型相等
module Identity : MONAD with type 'a m = 'a = ...
它是有效的
现在看来,签名中的“a”取代了“m”
这是破坏性替代的效果,当你写作时
module Identity : MONAD with type 'a m := 'a
您要求编译器将'am
的所有实例替换为'a
。
相反,带有
约束的标准为模块类型添加了类型相等
module Identity : MONAD with type 'a m = 'a
看看您的各种示例,您似乎混淆了这两者,并且在打算添加类型约束时使用了破坏性替换:
module OptionT(X:Monad) : MONAD with type 'a m = 'a = …
(* or *) module Option : MONAD with type 'a m = 'a option = …
而不是
module OptionT(X:Monad) : MONAD with type 'a m := 'a = …
(* nor *) module Option : MONAD with type 'a m := 'a option = …
现在看来,签名中的“a”取代了“m”
这是破坏性替代的效果,当你写作时
module Identity : MONAD with type 'a m := 'a
您要求编译器将'am
的所有实例替换为'a
。
相反,带有
约束的标准为模块类型添加了类型相等
module Identity : MONAD with type 'a m = 'a
看看您的各种示例,您似乎混淆了这两者,并且在打算添加类型约束时使用了破坏性替换:
module OptionT(X:Monad) : MONAD with type 'a m = 'a = …
(* or *) module Option : MONAD with type 'a m = 'a option = …
而不是
module OptionT(X:Monad) : MONAD with type 'a m := 'a = …
(* nor *) module Option : MONAD with type 'a m := 'a option = …
OP说他试过了,得到了类型'm'是必需的,但没有提供
。OP说他试过了,得到了类型'm'是必需的,但没有提供
。