2016-09-06 3 views
2
type FFRec<'state when 'state: (member Tape: Stack<unit -> unit>) 
        and 'state: (member Mem: ObjectPool) 
        and 'state: (member Str: CudaStream) 
        and 'state: (member Workspace: Workspace) 
        and 'state: (member IsInferenceOnly: bool)> = 
    { 
    W: d2M 
    b: d2M 
    a: d2M -> 'state -> d2M * 'state 
    } 

インターフェイスですべてのそれらのメンバーの制約を交換することが可能であるが、そのアプローチの小さな問題は、コンパイラは、私は例えば、このような機能を持っている場合ことを実現するために十分にスマートではないということです。メンバの制約を持つ型の省略形を作ることはできますか?

let inline reluInitializer (state: ^state) (a: ^a) = 
    let scale = (1.0f/sqrt(addDims a |> float32)) 
    fillRandomUniformMatrix((str state),a,scale,0.0f) 
    a 

^stateにはインターフェイスの制約があり、不可解なシグネチャが必要であり、実装ではレコードジェネリックパラメータ宣言のエラーが異なることに気付かないでしょう。

可能であれば、明示的なインターフェイスよりもメンバの制約を使用したいと思いますが、タイプの省略形を使用して上記の制約の宣言を短くする方法を見つけることができませんでした。それは現在のF#で可能でしょうか?

+0

キーワード 'inline'を調べます。 F#は、あなたがしようとしているもののための最良の近似です。 – asibahi

答えて

4

いいえ、型で静的に解決された型パラメータを使用することはできません。

静的に解決された型パラメーターはCLRでサポートされていないため、コンパイル時に消去する必要があります。これは、コールサイトでインライン化してILにコンパイルしない関数で行うことは可能ですが、タイプはIL表現を持たなければなりません。そうしないと、実行時にインスタンスを持つことができないからです。

あなたの制約は、すべてのメンバーに1つずつ、評価者関数の形で表現することを検討する必要があります。このようにして、あなたの型が「受け入れられない」型引数でコンパイルされても、その型は使用されないので、プログラム全体を効果的に制約します。

例の^stateパラメータで説明している問題については、私はそれが何であるかはよく分かりません。あなたの関数にはメンバーアクセスがないため、メンバーに関連するエラー。


コメントの質問に応じて:いいえ、再利用のためにタイプエイリアスにメンバー制約を含めることはできません。

+0

アクセッサ関数によって、 ''インラインで処理するv =(^ b:(メンバDispose:ユニット - >ユニット)v) 'のようなインライン関数の種類を意味する場合、私はそれらを全面的に使用しています。上に示したことは、2k LOCライブラリのほんの一部なので、実装を示す必要があるかどうかはわかりませんでした。通常のlet関数とは違って、コンパイラはクラス制約やレコードを明示的に書くのではなく、型制約を省略することができるかどうかを本当に求めていました。 –

+0

今、継承を使用してそれをしようとしています。継承の制約を使用する際に、本当に役に立たない型エラーが発生しています。基本的には、ライブラリ全体がインライン展開され、簡潔にするために静的に解決された型パラメータが使用されます。 –

+1

あなたはあなたの質問や問題をもっと明確にしませんでした。より具体的にお試しください。希望の結果やエラーメッセージとともにサンプルを提供してみてください。 –

関連する問題