【问题标题】:Optional argument in a method with ocaml使用 ocaml 的方法中的可选参数
【发布时间】:2013-06-17 23:23:23
【问题描述】:


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

让我解释一下。我有一个寻路类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 才会停止侮辱我。

提前感谢您的帮助:)

【问题讨论】:

  • 你是怎么调用这个方法的?
  • 哈,是的。例如:let path = self#getNodes#shorthestPath ~src:"begin" node in ...self#getNodes方法获取Graph实例。

标签: class methods ocaml optional-arguments


【解决方案1】:

不清楚你的情况,但我猜如下:

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 : &lt; x : int -&gt; int; .. &gt;。方法x的类型固定在这里。

后面定义的对象o独立于f的参数,类型为&lt; m : ?l:int -&gt; int -&gt; int; .. &gt;。不幸的是,这种类型与其他类型不兼容。

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

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 无法推断省略的可选参数,请尝试显式地给出一些关于它们的类型上下文。

【讨论】:

  • 显式上下文... 实际上,我认为最好的方法是为每个模块使用接口。但是,我的项目太先进了,无法做到这一点,而且我没有太多时间。但是现在强制我的变量的类型可能很适用。所以使用这段代码我没有问题:let path = self#getNodes#shorthestPath node in ...method private getNodes = match nodes with Some n -&gt; (n:Wally.graph) | None -&gt; failwith "Pathfinding is not initialized"
  • 非常感谢您的帮助。抱歉我不够清楚。
猜你喜欢
  • 2014-07-05
  • 1970-01-01
  • 2016-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多