1


我在方法类中遇到了可选参数的问题。

让我解释。我有一个寻路类graph(在 Wally 模块中)和一个他的方法shorthestPath。它使用可选参数。事实是,当我调用(使用或不使用可选参数)此方法 OCaml 返回类型冲突时:

Error: This expression has type Wally.graph
   but an expression was expected of type
     < getCoor : string -> int * int;
       getNearestNode : int * int -> string;
       shorthestPath : src:string -> string -> string list; .. >
   Types for method shorthestPath are incompatible

shorthestPath类型是:

method shorthestPath : ?src:string -> string -> string list

我同样尝试将选项格式用于可选参数:

method shorthestPath ?src dst =
  let source = match src with
    | None -> currentNode
    | Some node -> node
  in 
  ...

只有在我删除可选参数的情况下,OCaml 才会停止侮辱我。

预先感谢您的帮助 :)

4

1 回答 1

7

目前还不是很清楚你的情况是什么,但我猜如下:

let f o = o#m 1 + 2

let o = object method m ?l x = match l with Some y -> x + y | None -> x

let () = print_int (f o)   (* type error. Types for method x are incompatible. *)

使用地点(这里是 的定义f),对象的类型是从它的上下文中推断出来的。在这里,o : < x : int -> int; .. >。方法x的类型在这里是固定的。

o后面定义的对象独立于 的参数f并且具有类型< m : ?l:int -> int -> int; .. >。不幸的是,这种类型与其他类型不兼容。

一种解决方法是为使用站点提供更多关于可选参数的键入上下文:

let f o = o#m ?l:None 1 + 2  (* Explicitly telling there is l *)
let o = object method m ?l x = match l with Some y -> x + y | None -> x end

或给出类型o

class c = object
    method m ?l x = ...
    ...
end

let f (o : #c) = o#m 1 + 2   (* Not (o : c) but (o : #c) to get the function more polymoprhic *)
let o = new c
let () = print_int (f o)

我认为这更容易,因为通常事先有一个类声明。

这种带有可选参数的高阶函数使用之间的故障也发生在对象之外。OCaml 试图很好地解决它,但并不总是可行的。在这种情况下:

let f g = g 1 + 2
let g ?l x = match l with Some y -> x + y | None -> x
let () = print_int (f g)

打字很好。好的!

关键规则:如果 OCaml 无法推断省略的可选参数,请尝试显式地给出一些关于它们的类型上下文。

于 2013-06-20T23:28:39.183 回答