【问题标题】:OCaml: This expression has type int but an expression was expected of type MyFoo.ty (except MyFoo.ty is int)OCaml:此表达式的类型为 int,但表达式应为 MyFoo.ty 类型(MyFoo.ty 为 int 除外)
【发布时间】:2020-01-05 17:23:42
【问题描述】:

这是我的代码:

foo.ml:

module type ITy = sig
   type ty
end

module type IFoo = sig
   type ty
   val doo: ty -> ty
end

module Make (Ty: ITy): IFoo = struct
   type ty = Ty.ty
   let doo (x:ty) = x
end

main.ml:

module MyFoo = Foo.Make(struct
   type ty = int
end)

let () = assert(MyFoo.doo 3 = 3)

要编译,我使用:

$ corebuild main.native

这给了我:

+ ocamlfind ocamlc -c -w A-4-33-40-41-42-43-34-44 -strict-sequence -g -bin-annot -short-paths -thread -package core -ppx 'ppx-jane -as-ppx' -o main.cmo main.ml
File "main.ml", line 5, characters 26-27:
5 | let () = assert(MyFoo.doo 3 = 3)
                              ^
Error: This expression has type int but an expression was expected of type
         MyFoo.ty
Command exited with code 2.
Hint: Recursive traversal of subdirectories was not enabled for this build,
  as the working directory does not look like an ocamlbuild project (no
  '_tags' or 'myocamlbuild.ml' file). If you have modules in subdirectories,
  you should add the option "-r" or create an empty '_tags' file.

  To enable recursive traversal for some subdirectories only, you can use the
  following '_tags' file:

      true: -traverse
      <dir1> or <dir2>: traverse

Compilation unsuccessful after building 4 targets (3 cached) in 00:00:01.

我希望我的代码能够成功编译 b.c。我是一个 OCaml 菜鸟,当我在 main.ml 中调用 Foo.Make 函子来创建 MyFoo 时,我给它一个输入结构 type ty = int。我可能做错了什么,但未能找到专门讨论此问题的文档。也许我在某处使用了错误的运算符。任何帮助将不胜感激。

【问题讨论】:

标签: ocaml


【解决方案1】:

这是你想要完成的吗?

module type ITy = sig
   type ty
end

module type IFoo = sig
   type ty
   val doo: ty -> ty
end

module Make (Ty: ITy): (IFoo with type ty := Ty.ty) = 
struct
   let doo x = x
end

module MyFoo = Make(struct
   type ty = int
end)

let () = assert(MyFoo.doo 3 = 3)

【讨论】:

  • 好的,谢谢。我确实发现 Yawar 的评论很有用,但从来没有回答我自己的问题。如果其他人遇到这种情况,重要的是说 (IFoo with type ty := Ty.ty) 的部分,它将 IFoo 接口转换为另一个接口,上面写着“向外部世界公开/共享ty”。这些称为共享约束。
  • 好吧,我有点撒谎了。最重要的是,:= 而不仅仅是 = 意味着使用称为破坏性替换的东西,它会进行进一步的转换以删除输出签名中ty 的所有实例并将其替换为基础类型。 IMO 这一切听起来比实际上更复杂——访问修饰符
  • 此外,此功能在公元前很有用。如果你有,让我们说一个内部变体类型,那么你可能想要阻止外部访问该变体类型的构造函数并强制外部使用某种前端工厂函数。同样,请参阅上面 Yamar 的评论以获取 o'reilly 书的链接,该书详细介绍了这一点,其中包含与 ocaml.org 教程不同的完整示例
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-31
  • 1970-01-01
  • 2018-04-30
相关资源
最近更新 更多