2014-12-06 73 views
7

这里有一个小例子,从我的代码演示问题:值没有足够多态

module Substring = struct 
    type t = { 
    base: string; 
    pos: int; 
    len: int 
    } 
end 

module Parser = struct 
    type 'a t = Substring.t -> ('a * Substring.t) option 
    let return x s = Some (x, s) 
end 

type (_, _) t = 
    | TryParse : unit Parser.t -> ('a, 'a) t 
    | Parse : 'b Parser.t -> ('a, 'b -> 'a) t 
    | Concat : ('b, 'c) t * ('a, 'b) t -> ('a, 'c) t 

let p = Parse (Parser.return "xxx") 

我的问题是,我想val p : ('a, string -> 'a) t具有多态性,但OCaml的使'a弱:val p : ('_a, string -> '_a)。我很确定我在这里受到价值限制的困扰,我不太清楚如何解决这个问题。

回答

5

是的,这是价值限制。你需要eta-扩大有问题的定义,像这样:

let p = Parse (fun x -> Parser.return "xxx" x) 

烦人,不是吗?

如果你想绑定是多态的,那么你通常必须确保它是一个“语法值”。包含部分应用程序的表达式不具备资格(因为通常部分应用程序可能会产生影响),但(fun ...)没问题。