Types 标记参数

Types 标记参数,types,ocaml,Types,Ocaml,考虑以下顶级会话,该会话定义了一个带有标签参数f的函数,但在调用该函数时不使用标签: # let dummy x y ~f:f = x-y+(f());; val dummy : int -> int -> f:(unt -> int) -> int = <fun> # dummy 2 3 (fun () -> 5);; - : int = 4 #让虚拟对象xy~f:f=x-y+(f());; val虚拟值:int->int->f:(unt->int

考虑以下顶级会话,该会话定义了一个带有标签参数
f
的函数,但在调用该函数时不使用标签:

# let dummy x y ~f:f = x-y+(f());;
val dummy : int -> int -> f:(unt -> int) -> int = <fun>

# dummy 2 3 (fun () -> 5);;
- : int = 4
#让虚拟对象xy~f:f=x-y+(f());;
val虚拟值:int->int->f:(unt->int)->int=
#假人23(乐趣()->5);;
-:int=4
这个很好用。 但是,如果我尝试对中的函数执行相同的操作,则如下所示:

# open Core.String;;

# let t = Table.create();;
val t : ('a, '_weak1) Core.String.Table.t_ = <abstr>

# Table.find_or_add t "a" ~default:(fun () -> 5);; (*This works fine*)
- : int = 5

# Table.find_or_add t "b" (fun () -> 1);; (*This does not typecheck*)
#opencore.String;;
#设t=Table.create();;
val t:('a','u weak1)Core.String.Table.t_k1=
#Table.find_或_add t“a”~默认值:(fun()->5);;(*这很好用*)
-:int=5
#Table.find_或添加t“b”(fun()->1);;(*这不进行类型检查*)
我在
t
上被抛出了一个类型错误,并说:

错误:此表达式的类型为('a,int)Core.String.Table.t_=(Core.String.Table.key,int)Base.Hashtbl.t,但表达式的类型应为('b,'c->'d)Core.String.Table.t_=(Core.String.Table.key,'c->'d)Base。Hashtbl.t type int与类型'c->'d不兼容


我无法解释这为什么不进行打字检查。如果有人能向我解释为什么前者有效,但后者无效,我将不胜感激。

不同之处在于,您的示例有一个具体的返回类型,而
find\u或\u add
是多态的。其类型签名为:

val查找或添加:('a,'b)t->'a键->默认值:(单位->'b)->'b
由于currying和
'b
可以是函数,带省略标签的参数将被推断为属于返回的函数,这就是为什么错误消息会说“表达式应为('b,'c->'d)Core.String.Table.t类型”。只有当应用程序为total时,才可以省略标签,在本例中不是total

我相信您只需在
t
中添加一个类型注释就可以解决这个问题,但是,从那时起,返回类型将是具体的,并且应用程序总数:

让t:(Table.key,int)Hashtbl.t=Table.create();;

不同之处在于,您的示例有一个具体的返回类型,而
find\u或\u add
是多态的。其类型签名为:

val查找或添加:('a,'b)t->'a键->默认值:(单位->'b)->'b
由于currying和
'b
可以是函数,带省略标签的参数将被推断为属于返回的函数,这就是为什么错误消息会说“表达式应为('b,'c->'d)Core.String.Table.t类型”。只有当应用程序为total时,才可以省略标签,在本例中不是total

我相信您只需在
t
中添加一个类型注释就可以解决这个问题,但是,从那时起,返回类型将是具体的,并且应用程序总数:

让t:(Table.key,int)Hashtbl.t=Table.create();;