2017-02-16 4 views
4

Ich habe Aktionsdaten, die wie folgt aussieht:F # Wie übertrage ich die Schnittstelle zu einer Funktion?

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

Später ich ShowHideNotCompletedData oder ShowHideCompletedData an eine Funktion zu übergeben bin versucht, nur die Funktion für eine boolean „Show“ Mitglied kümmert sich aber kann nicht herausfinden, wie man/cast passieren es:

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 

Aber wie man diese Funktion nennt?

let setShowFn = setShowItem (data :> IHasShow) not 

Fehler:

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

Versuchte

let setShowFn = setShowItem data not 

Fehler:

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

Gibt es eine Möglichkeit, um diese andere als Kopie Paste setShowItem eine ShowHideNotCompletedData nehmen und einen ShowHideCompleted ?

Wenn es hilft; der vollständige Quellcode ist hier:

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} 

ich noch tun frage mich, wie eine generische Art zu definieren, und dass übergeben: https://github.com/amsterdamharu/riot_redux_fable

Die einfachste Lösung, um die Daten, sondern nur die Bool nicht passieren war.

Antwort

3

In Ihrer aktuellen Lösung sind Ihre beiden Typen ShowHideNotCompletedData und ShowHideCompletedData Datensätze. Sie haben alle Felder der Schnittstelle, implementieren sie aber nicht explizit. Die Lösung ist, die Schnittstelle zu machen deutlich:

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

Instantiate als ShowHideNotCompletedData true. Für alternative Lösungen möchten Sie vielleicht einige der SO-Fragen zur Duck Typisierung, zum Beispiel this

Mit allem gesagt: Ich habe eine Ahnung, dass Ihre Datentypdefinition ein wenig zu kompliziert ist. @robkuz hat eine Antwort geschrieben, die ohne die Schnittstelle auskommt. Ihr eigener Vorschlag, einfach einen Bool in die Funktion zu überführen, erscheint in Sachen Modularität und Testbarkeit noch besser.

3

Ich muss zugeben: Ich mag keine Schnittstellen in F # - nicht im Allgemeinen, aber ich denke syntaktisch sind sie eine totale Katastrophe. Also verwende ich häufig Inline-Funktionen mit Typ-Constraints.
Achtung: diese Art von Code verwendet wird wahrscheinlich ein Dutzend Welpen zu töten oder zu sortieren

Der erste, was Ihre Schnittstelle und die Implementierung es loszuwerden (was man sowieso ;-) vergessen hat)

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

dann schreiben, die wirklich verrückt aussehenden Funktion

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

und wenden es

let setShowItem data = 
    match data with 
    | ShowHideNotCompleted x -> show x 
    | ShowHideCompleted x -> show x 
+2

Ich bin mit dir auf die Abneigung der Schnittstellen. Ihre Lösung ist idiomatischer als Schnittstellen. Ich bin mir nicht sicher ob, ob es die beste Lösung für das vorliegende Problem ist, der Datentyp scheint übermäßig komplex zu sein, aber das OP lieferte nicht viel Kontext. –

+0

Oder "lass inline zeigen x = (^ T: (member show: bool) (x))' type inferenz FTW :-) – CaringDev

Verwandte Themen