【发布时间】:2019-07-30 14:22:10
【问题描述】:
我已经编写了以下仿函数和实例,
module type Set = sig
type elt
type t
val empty : t
val insert : elt -> t -> t
val find : elt -> t -> bool
end
module type OrderedSet = sig
type t
val compare : t -> t -> int
end
module BstSet(M: OrderedSet) : Set = struct
type elt = M.t
type t = M.t tree
let empty = Leaf
let rec insert x tr = match tr with
| Leaf -> Node(Leaf, x, Leaf)
| Node (lt, y, rt) -> let c = M.compare x y in
if c < 0 then Node (insert x lt, y, rt)
else if c > 0 then Node (lt, y, insert x rt)
else Node (lt, y, rt)
let rec find x tr = match tr with
| Leaf -> false
| Node (lt, y, rt) -> let c = M.compare x y in
if c = 0 then true
else if c < 0 then find x lt
else find x rt
end
module MyString : OrderedSet = struct
type t = string
let compare s1 s2 = compare s1 s2
end
module StringSet = BstSet(MyString);;
StringSet.empty |> StringSet.insert "abc";;
编译器报错
StringSet.empty |> StringSet.insert "abc";;
^^^^^
Error: This expression has type string but an expression was expected of type
StringSet.elt = BstSet(MyString).elt
Command exited with code 2.
这让我很困惑,因为我本以为编译器会发生这样的事情:
- 我们用函子构造
BstSet(MyString),所以参数M是MyString。 - 这意味着当我们调用
M.t时,这是string。 - 这意味着
elt是string。 - 这意味着,在
insert的签名中,我们有一个函数string -> string tree -> string tree。
所以这应该编译。或者更直接地说,我会认为StringSet.elt 将等于string。
【问题讨论】: