在OCaml中输入共享 - typechecker错误 [英] Type sharing in OCaml - typechecker error
问题描述
模块类型Inc =
sig
类型t
val inc:t - > t
结束
模块类型Dec =
sig
类型t
val dec:t - > t
end
模块合并(I:Inc)(D:Dec类型为t = I.t)=
struct
let merge x = x |> I.inc |> D.dec
end
module IntInc:Inc =
struct
type t = int
let inc x = x + 10
end
模块IntDec:Dec =
struct
type t = int
let dec x = x - 8
end
模块Combiner =合并(IntInc)(IntDec)
我得到以下错误:
文件simple.ml,第30行,字符35-41:
错误:签名不匹配:
模块不match:
sig type t = IntDec.t val dec:t - > t end
不包含在
中sig type t = IntInc.t val dec:t - > t结束
类型声明不匹配:
类型t = IntDec.t
不包含在
类型中t = IntInc.t
文件simple.ml ,第13行,字符38-50:预期声明
文件simple.ml,第9行,字符13-14:实际声明
我认为 D:Dec类型为t = It
约束将确保 Dt = It
。为什么不是这样?
更有趣的是,当我删除 module Combiner = Merger(IntInc)(IntDec)
行编译没有错误。
我的问题是:我做错了什么?
您对 Merger
的约束定义是完全正确的,这就是为什么该部分无误地编译。
说,唯一不编译的部分是 module Combiner = Merger(IntInc)(IntDec)
。这是因为,据OCaml所知,约束 IntInt.t = IntDec.t
未被满足。原因是OCaml不知道 IntInt.t
和 IntDec.t
是 INT
。它只知道 IntInt:Inc
和 IntDec:Dec
- 其他所有内容都是模块的私有细节。 / p>
若要解决此问题,可以将模块的标题更改为 IntInt:(Inc类型为t = int)
和 IntDec :( Dec类型为t = int)
,使类型 t
成为模块公共接口的一部分,而不是一个私人的细节,允许OCaml在解决合并
函子的约束时使用这些信息。
When compiling this program:
module type Inc =
sig
type t
val inc : t -> t
end
module type Dec =
sig
type t
val dec : t -> t
end
module Merger (I : Inc) (D : Dec with type t = I.t) =
struct
let merge x = x |> I.inc |> D.dec
end
module IntInc : Inc =
struct
type t = int
let inc x = x + 10
end
module IntDec : Dec =
struct
type t = int
let dec x = x - 8
end
module Combiner = Merger (IntInc) (IntDec)
I get the following error:
File "simple.ml", line 30, characters 35-41:
Error: Signature mismatch:
Modules do not match:
sig type t = IntDec.t val dec : t -> t end
is not included in
sig type t = IntInc.t val dec : t -> t end
Type declarations do not match:
type t = IntDec.t
is not included in
type t = IntInc.t
File "simple.ml", line 13, characters 38-50: Expected declaration
File "simple.ml", line 9, characters 13-14: Actual declaration
I thought that D : Dec with type t = I.t
constraint will ensure that D.t = I.t
. Why it is not so?
What is more interesting, when I remove module Combiner = Merger (IntInc) (IntDec)
line it compiles without errors.
My question is : What am I doing wrong?
Your definition of Merger
with the constraint is perfectly correct, which is why that part compiles without error.
As you said, the only part that doesn't compile is module Combiner = Merger (IntInc) (IntDec)
. This is because, as far as OCaml knows, the constraint IntInt.t = IntDec.t
is not met. The reason for that is that OCaml does not know that IntInt.t
and IntDec.t
are int
. All it knows is that IntInt : Inc
and IntDec : Dec
- everything else is a private detail of the module.
To fix this problem you can change the module's headers to IntInt : (Inc with type t = int)
and IntDec : (Dec with type t = int)
, making the type t
a part of the modules' public interface rather than a private detail, allowing OCaml to use that information when resolving the constraint of the Merger
functor.
这篇关于在OCaml中输入共享 - typechecker错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!