我有以下内容:
Person
模块类型,包含获取名字和姓氏的方法:
module type Person = sig
type t
val first : t -> string
val last : t -> string
end
使用PersonUtils
函数扩展Person
的{{1}}仿函数:
name
和module PersonUtils (Person: Person) : sig
type t
val name : t -> string
end = struct
include Person
let name p = Person.first p ^ " " ^ Person.last p
end
模块如下:
Main
在module Main : sig
type t
val name : t -> string
end = struct
include PersonUtils(struct
type t = {
first: string;
last: string;
}
let first p = p.first
let last p = p.last
end)
end
中,我想添加一个额外的Main
函数:所以我将以下内容添加到签名和模块中:
loud_first_name
但是,似乎module Main : sig
type t
val name : t -> string
(* New *)
val loud_first_name : t -> string
end = struct
include PersonUtils(struct
type t = {
first: string;
last: string;
}
let first p = p.first
let last p = p.last
end)
(* New *)
let loud_first_name p = String.uppercase p.first
end
不再知道我的类型loud_first_name
的结构,所以我留下了错误t
。
我的问题是:我如何创建像Unbound record field first
这样的方法,以便他们仍然可以访问我的记录字段?我试图将loud_first_name
类型提升到一个级别,但在我的仿函数的参数中使用它时遇到了麻烦。
t
答案 0 :(得分:1)
看起来像是type nonrec t = t
(感谢Étienne Millon)并将模块与签名组合在一起修复了我的问题。
module type PUSig = sig
type t
val name : t -> string
end
module PersonUtils (Person: Person) : PUSig with type t = Person.t = struct
include Person
let name p = Person.first p ^ " " ^ Person.last p
end
module Main : sig
type t = {
first: string;
last: string;
}
val loud_first_name : t -> string
end = struct
type t = {
first: string;
last: string;
}
include (PersonUtils(struct
type nonrec t = t
let first p = p.first
let last p = p.last
end) : PUSig with type t := t)
(* New *)
let loud_first_name p = String.uppercase_ascii p.first
end
答案 1 :(得分:0)
您必须在签名中注明您的类型是相同的,如果您只在结构中指明,则信息将会丢失。
module PersonUtils (Person: Person) : sig
type t = Person.t
val name : t -> string
end
= struct
include Person
let name p = Person.first p ^ " " ^ Person.last p
end
另一种方法(我建议)是在模块类型声明中添加with
子句。
module PersonUtils (Person: Person) : sig
type t
val name : t -> string
end
with type t = Person.t
= struct
include Person
let name p = Person.first p ^ " " ^ Person.last p
end
虽然签名声明中没有直接显示这些信息,但它允许您单独声明您的签名和您的仿函数:
module type Personutils_T = sig
type t
val name : t -> string
end
module PersonUtils (Person: Person) : Personutils_T
with type t = Person.t
= struct
include Person
let name p = Person.first p ^ " " ^ Person.last p
end