gpt4 book ai didi

ocaml - 多态变体子类型实现与签名不匹配

转载 作者:行者123 更新时间:2023-12-04 00:53:25 25 4
gpt4 key购买 nike

我有以下代码:

module Test : sig
type +'a t
val make : int -> [< `a | `b] t
end = struct
type 'a t = Foo of int | Bar of string

let make = function
| 0 -> (Foo 0 : [`a] t)
| _ -> (Bar "hi" : [`a] t)
end

您可能会注意到,抽象类型 'a t在其类型参数 'a 中声明为协变的,以及 make构造函数被声明为返回多态变体案例的子类型 ab .

在我的实现中 make , 返回子类型 [a] t由于子类型处于返回类型位置,因此仍应遵循协方差规则。

但是,我收到以下错误:
Error: Signature mismatch:
...
Values do not match:
val make : int -> [ `a ] t
is not included in
val make : int -> [< `a | `b ] t
File ".../cov.ml", line 3, characters 3-34:
Expected declaration
File ".../cov.ml", line 7, characters 7-11:
Actual declaration

关于如何让 OCaml 相信 make 的任何建议函数确实返回了 [a | b] t 的有效子类型?

最佳答案

我做了一些实验:

# type 'a t = Foo of int | Bar of string;;
type 'a t = Foo of int | Bar of string
# let make = function
| 0 -> (Foo 0 : [`a] t)
| _ -> (Bar "hi" : [`a] t);;
val make : int -> [ `a ] t = <fun>
# (make : int -> [< `a | `b] t);;
- : int -> [ `a ] t = <fun>
# let make2 : int -> [< `a | `b] t = make;;
val make2 : int -> [ `a ] t = <fun>
# let make3 = (make :> int -> [< `a | `b] t);;
val make3 : int -> [< `a | `b ] t = <fun>

所以,显然 OCaml 确实承认父类(super class)型关系,但仍然更喜欢坚持更精确的子类型,除非给予强制。其他人可能知道类型理论原因。但因为你的问题只是

[...] how to convince OCaml [...]



我的回答是:像这样使用强制
module Test : sig
type +'a t
val make : int -> [< `a | `b] t
end = struct
type 'a t = Foo of int | Bar of string

let make = (function
| 0 -> (Foo 0 : [`a] t)
| _ -> (Bar "hi" : [`a] t)
:> int -> [< `a | `b] t)
end

关于ocaml - 多态变体子类型实现与签名不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48237453/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com