为什么这个OCaml模式匹配不能编译?

时间:2015-07-06 15:28:11

标签: pattern-matching ocaml

我有一个模块接口

module type Enum = sig
type t
val toInt : t -> int
val fromInt : int -> t
end

然后我有一个模块

module Navigability : Enum = struct
type t=
AB
| BA
| Both
| None

let toInt = function
| BA   -> -65536
| Both -> -1
| None -> 0
| AB   -> 65535

let fromInt = function
| -65536 -> BA  
| -1     -> Both
| 0      -> None
| 65535  -> AB  
| _ -> None

end

一旦我添加以下函数,代码就无法编译:

let fun = function
| Navigability.t.BA   -> false
| Navigability.t.Both -> true
| Navigability.t.None -> false
| Navigability.t.AB   -> true 

如果我把它放在模块中并取消界面,它就可以了。

有谁可以告诉我为什么以及如何?

2 个答案:

答案 0 :(得分:2)

当您编写Navigability: Enum时,您正在“密封”模块,以使其界面仅限于Enum中的内容。值BA等不在那里。

答案 1 :(得分:2)

module type是对绑定到它的模块外部可见内容的严格规范。因此,正如杰弗里·斯科菲尔德在答案中所说,键入module Navigability : Enum可确保Navigability之外的唯一已知事物将是Enum中定义的事物,并且您的类型构造函数不属于with这一点。

确保类型可见性的一种简单方法是将其声明在模块之外,然后将其与type nav = AB | BA | Both | None module Navigability : Enum with type t = nav = struct type t = nav (* put other definitions here *) end let f = function | BA -> false | Both -> true | None -> false | AB -> true 子句绑定:

Navigability.t.AB

作为旁注,您的构造Navigability.AB不正确,应该只是fun。此外,Navigability无法用作函数或变量名称,因为它是关键字。

如果您希望仅通过Enum访问导航类型,则可以在删除Navigability约束时保留定义。什么都不会阻止您以后使用Enum作为<asp:Button ID="btnPopulate" runat="server" Text="Populate Grid" onclick="btnPopulate_Click" /><br /><br /> <asp:GridView ID="gvDemo" runat="server" AutoGenerateColumns="false"> <Columns> <asp:BoundField DataField="FirstName" HeaderText="First Name" /> <asp:BoundField DataField="LastName" HeaderText="Last Name" /> </Columns> </asp:GridView> <br /> <asp:TextBox ID="txtKeyword" runat="server" Text=""></asp:TextBox> <asp:Button ID="btnFilter" OnClientClick="Filter();return false;" runat="server" Text="Filter" />