2016-11-12 14 views
2

私はOcamlの練習問題としてReactのタイプバージョンを作成しようとしています。 これをより機能的にするために、レンダリングの引数としてレコードを渡しています。コンパイラはlet newInstance = { props; state = nextState; updater = (mkUpdater props) }updater = (mkUpdater props)の型を推論できない理由を私は理解していない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)) 

一つのことです。

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 タイプ 'a - >' b - > 'cはタイプ(' e、 'c)と互換性がありませんreactInstance " – Drup

+0

エラーのように見える複数のものがあります。あなたの操作の意味論が何であるかを知らなくてもそれらを解決するのは難しいです。しかし、最初に私に飛びつくのは、アップデーターフィールドの '' a''です。あなたはここでforallを使いたいのですか?それは非常に便利ではないようです。 – Drup

答えて

2

タイプ変数'_a(実際の文字は重要ではありませんが、重要なことはアンダースコアです)は、いわゆる弱いタイプの変数です。これは一般化することができない変数であり、1つの具体的な型だけで置き換えることができます。これは可変値のようですが、タイプの領域です。

弱型変数'_aで示される型は、汎用型変数で示される型には含まれません。さらに、コンパイル単位をエスケープすることもできず、隠されているか具体化されている必要があります。

弱い型の変数は、式が純粋な値でない(構文的に定義されている)ときに作成されます。通常は、関数アプリケーションか抽象のいずれかです。一般的には、部分的に適用された関数を通常の関数アプリケーションに置き換えて、すべての関数引数、すなわちupdater = (fun props f i e -> mkUpdater props f i e)を列挙することで、いわゆるエタ拡張を実行して弱い型変数を取り除くことができます。

+0

大きな説明に感謝します! – Seneca

関連する問題