2016-11-12 141 views
2

我正在嘗試在Ocaml中作爲練習的打字版本。 爲了使它更實用,我將一條記錄作爲參數傳遞給渲染。Ocaml不正確的類型推斷

type ('props,'state) reactInstance = 
    { 
    props: 'props; 
    state: 'state; 
    updater: 'a . ('props,'state) reactInstance -> 'a -> 'state -> unit;} 
and ('props,'state) reactClass = 
    { 
    getInitialState: unit -> 'state; 
    render: ('props,'state) reactInstance -> element;} 

module type ComponentBluePrint = 
    sig 
    type props 
    type state 
    val getInitialState : unit -> state 
    val render : (props,state) reactInstance -> element 
    end 

module type ReactClass = 
    sig 
    type props 
    type state 
    val mkUpdater : 
    props -> 
    ((props,state) reactInstance -> 'e -> state) -> 
     (props,state) reactInstance -> 'e -> unit 
    val reactClass : (props,state) reactClass 
    end 

module CreateComponent(M:ComponentBluePrint) = 
    (struct 
    include M 
    let rec mkUpdater props f i e = 
     let nextState = f i e in 
     let newInstance = 
     { props; state = nextState; updater = (mkUpdater props) } in 
     () 

    let reactClass = 
     { render = M.render; getInitialState = M.getInitialState } 
    end : (ReactClass with type props = M.props and type state = M.state)) 

有一件事我不明白的是爲什麼編譯器不能在let newInstance = { props; state = nextState; updater = (mkUpdater props) }推斷updater = (mkUpdater props)類型。

Error: Signature mismatch: 
     Values do not match: 
     let mkUpdater : 
    props => 
    (reactInstance props state => '_a => '_b) => 
    reactInstance props state => '_a => unit 
     is not included in 
     let mkUpdater : 
    props => 
    (reactInstance props state => 'e => state) => 
    reactInstance props state => 'e => unit 

'_a和'e有什麼區別? 它看起來和我完全一樣。我如何進行這種類型的檢查?

+0

您提供的錯誤不是您的文件生成的實際錯誤。正確的錯誤是「錯誤:該表達式具有類型('a - >'b - >'c) - >'a - >'b - >'d 但是期望表達式爲 ('e,'c )reactInstance - >'f - >'c - >單元 類型'a - >'b - >'c與類型不兼容('e,'c)reactInstance 「 – Drup

+0

有很多事情看起來像錯誤該文件,但如果不知道操作的假定語義如何,很難解決它們。然而,跳到我的第一件事是更新器領域的''a。',你確定你想在這裏使用嗎?這看起來不太有用。 – Drup

回答

2

一個類型變量'_a(實際的字母並不重要,關鍵的是下劃線)是一個所謂的弱類型變量。這是一個不能概括的變量,也就是說,它只能被一個具體類型替代。這就像一個可變的價值,但在類型領域。

用弱類型變量'_a表示的類型不包含在用泛型類型變量表示的類型中。而且,它甚至無法逃脫編制單位,應該隱藏或具體化。

當表達式不是純值(在語法上定義)時會創建弱類型變量。通常,它是一個函數應用程序或抽象。當通過枚舉所有函數參數(即updater = (fun props f i e -> mkUpdater props f i e))將部分應用函數替換爲普通函數應用程序時,通常可以通過執行所謂的eta-expansion來擺脫弱類型變量。

+0

感謝您的好解釋! – Seneca