2017-02-16 9 views
4

私はのように見える行動データがあります。F#インターフェイスを関数に渡す方法は?

type IHasShow = 
    abstract member show:bool 
type ShowHideNotCompletedData  = {show:bool} 
type ShowHideCompletedData   = {show:bool} 
[<Pojo>] 
type ActionData = 
    | ShowHideNotCompleted of ShowHideNotCompletedData 
    | ShowHideCompleted of ShowHideCompletedData 

その後、私は関数にShowHideNotCompletedDataまたはShowHideCompletedDataに合格しようとしています、機能だけブール「ショー」メンバーの世話が、/キャストを渡す方法を見つけ出すカントをそれ:

let setShowItem (data:IHasShow) negate item = 
    if data.show && (negate item.completed) then 
    { item with show = true} 
    else if (negate item.completed) then 
    { item with show = false} 
    else 
    item 

しかし、この関数をどのように呼び出すのですか?

let setShowFn = setShowItem (data :> IHasShow) not 

エラー:

Type constraint mismatch. The type 
    'ShowHideNotCompletedData'  
is not compatible with type 
    'IHasShow' 

let setShowFn = setShowItem data not 

エラーしようとしました:

The type 'ShowHideNotCompletedData' is not compatible with the type 'IHasShow' 

はShowHideNotCompletedDataとShowHideCompletedを取ってペーストsetShowItemをコピーするよりも、この他に方法はあります?

役立つ場合は、完全なソースコードはここにある:

let setShowItem show negate item = 
    if (negate item.completed) then//simplified if statement 
    { item with show = show} 
    else 
    item 
//... 

| ShowHideCompleted data -> 
    let setShowFn = setShowItem data.show id 
    { state with 
     showCompleted = data.show 
     items = state.items 
     |> Array.map setShowFn} 

私はまだやるジェネリック型を定義し、それを渡す方法を疑問に思う:https://github.com/amsterdamharu/riot_redux_fable

最も簡単な解決策は、データだけブール値を渡さないことでした。

答えて

3

現在のソリューションでは、ShowHideNotCompletedDataShowHideCompletedDataの2種類がレコードです。彼らはインタフェースのすべてのフィールドを持っていますが、明示的にそれらを実装していません。解決策は、インターフェイスを明示的にすることです:

type ShowHideNotCompletedData(show) = 
    interface IHasShow with 
     member this.show = show 
type ShowHideCompletedData(show) = 
    interface IHasShow with 
     member this.show = show 

ShowHideNotCompletedData trueとしてインスタンス化します。代わりの解決法については、アヒルのタイプに関するSOの質問の一部を参考にしたいと思うかもしれません。例えば、this

あなたのデータ型定義がちょっと複雑すぎます。 @robkuzさんは、インターフェイスなしで回答を投稿しました。ブールを関数に渡すというあなた自身の提案は、モジュール性とテスト容易性の点でさらに優れているようです。

3

私は認める必要があります:私はF#のインターフェイスが好きではありません - 一般的ではありませんが、構文的には完全なデスタスターだと思います。 したがって、タイプ制約を持つインライン関数を使用することはしばしばありません。
Achtung:おそらくダースの子犬を殺したり、ソート

最初のものは、あなたのインターフェイスとその実装(あなたがとにかく忘れてしまった;-))を取り除く

type ShowHideNotCompletedData  = {show:bool} 
type ShowHideCompletedData   = {show:bool} 
type ActionData = 
    | ShowHideNotCompleted of ShowHideNotCompletedData 
    | ShowHideCompleted of ShowHideCompletedData 

ますこの種のコードを使用してそして、それは本当にクレイジー探している機能に

let inline show< ^T when ^T : (member show : bool)> (x:^T) = 
     (^T : (member show : bool)(x)) 

を書いて、

let setShowItem data = 
    match data with 
    | ShowHideNotCompleted x -> show x 
    | ShowHideCompleted x -> show x 
それを適用210
+2

私はインターフェイスの嫌悪にあなたと一緒にいます。あなたのソリューションは、インターフェイスよりも慣れています。私はそれが手元の問題のための最善の解決策であるかどうかはわかりませんが、データ型は非常に複雑に見えますが、OPはあまりコンテキストを提供しませんでした。 –

+0

または 'インライン表示x =(^ T :(メンバーショー:ブール)(x))'型推論FTW :-) – CaringDev

関連する問題