Optional argument in a method with ocaml

北慕城南 提交于 2019-12-11 13:00:14

问题



I encounter a problem with a optional argument in a method class.

let me explain. I have a pathfinding class graph (in the Wally module) and one his method shorthestPath. It use a optional argument. The fact is when I call (with or not the optional argument) this method OCaml return a conflict of type :

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

whereas shorthestPath type is :

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

I same tried to use the option format for a optional argument :

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

Only in the case where I remove the optionnal argument, OCaml stop to insult me.

Thank you in advance for your help :)


回答1:


It is not very clear what your situation is but I guess the following:

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. *)

The use site (here the definition of f), the type of object is inferred from its context. Here, o : < x : int -> int; .. >. The method x's type is fixed here.

The object o defined later is independent from the argument of f and has the type < m : ?l:int -> int -> int; .. >. And unfortunately this type is incompatible with the other.

A workaround is to give more typing context to the use site about the optional argument:

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

Or give the type of 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)

I think this is easier since there is usually a class declaration beforehand.

This kind of glitch between higher order use of functions with optional arguments happens also outside of objects. OCaml tries to resolve it nicely but it is not always possible. In this case:

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

is nicely typed. Nice!

The key rule: if OCaml cannot infer about omitted optional arguments, try giving some type context about them explicitly.



来源:https://stackoverflow.com/questions/17224901/optional-argument-in-a-method-with-ocaml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!