2014-12-06 101 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 ...)沒問題。