2016-03-21 4 views
4

Ich habe einen Code, der wie folgt aussieht:Wie kann ich die Zwischenergebnisse von jedem Schritt einer mehrstufigen Pipeline-Funktion erhalten?

this.GetItemTypeIdsAsListForOneItemTypeIdTreeUpIncludeItemType itemType.AutoincrementedId 
|> Array.map (fun i -> i.AutoincrementedId) 
|> Array.map (BusinessLogic.EntityTypes.getFullSetOfEntityTypeFieldValuesForItemTypeAid item.Autoincrementedid) 
|> Array.fold Array.append [||] 
|> Array.map (fun fv -> { fv with ReferenceAutoId = aid }) 
|> Array.toSeq 
|> Seq.distinctBy (fun fv -> fv.Fieldname) 
|> Seq.toArray 

Manchmal solcher Code wird das ungewöhnliche Ergebnis, das ich erklären müssen. Normalerweise gibt es keinen Fehler im Code. In den Daten ist ein Fehler aufgetreten. Und ich muss erklären, warum diese Daten nicht korrekt sind. Was ist der beste Weg, es zu tun?

Ich möchte nur auf die Liste in jedem Schritt dieses Ausdrucks zu sehen.

Etwas wie:

func data 
|> func2 && Console.WriteLine 
|> func3 && Console.WriteLine 
.... 

Eingang holen, teilen Sie es auf zwei. Übergeben Sie eine der Ausgaben an die nächste Funktion und die zweite Ausgabe an die Konsole.

+0

Normalerweise gibt es keinen Fehler im Code. In den Daten ist ein Fehler aufgetreten. Und ich muss erklären, warum diese Daten nicht korrekt sind. – demas

+0

Sie Titel und Frage sind irreführend. Sie bitten um Hilfe beim Debuggen, fragen dann aber nach dem besten Komponententest. Die Art, wie ich dies tun würde, ist, es als eine Zusammensetzung von Funktionen zu betrachten und jede Funktion einzeln zu testen. Wenn Ihr Test fundiert ist, sollte das Zusammenstellen der Funktionen keine unerwarteten Ergebnisse z. Fehler. Stellen Sie sich vor, Sie haben die Funktion a + b * c^d - fx/gx. Sie würden +, -, *, /,^und die Funktionen f und g getrennt testen. Durch das Ausführen von Mathe können Sie darauf vertrauen, dass der Ausdruck funktioniert, obwohl er aus einfacheren Funktionen/Ausdrücken besteht. –

+0

Haben Sie [bahnorientierte Programmierung] (https://fsharpfforfunandprofit.com/posts/recipe-part2/) gesehen? –

Antwort

9

Für eine schnelle und schmutzige Lösung, man kann immer eine Funktion wie diese hinzu:

// ('a -> unit) -> 'a -> 'a 
let tee f x = f x; x 

Wenn Sie zum Beispiel eine Zusammensetzung, wie diese:

[1..10] 
|> List.map string 
|> String.concat "|" 

Sie einfügen können tee um eine Nebenwirkung zu erreichen:

[1..10] 
|> List.map string 
|> tee (printfn "%A") 
|> String.concat "|" 

Das ist nicht funktionsfähig, aber kann in einer Prise verwendet werden, wenn Sie nur einige Zwischenwerte betrachten müssen; z.B. zur Fehlerbehebung.

Andernfalls könnte die Anwendung der State monad für eine "richtige" funktionelle Lösung angebracht sein. Dadurch können Sie den Status während der Berechnung mitnehmen. Der Status könnte zum Beispiel benutzerdefinierte Nachrichten enthalten, die auf dem Weg gesammelt wurden ...

Wenn Sie nur "beenden" wollen, sobald Sie feststellen, dass etwas nicht stimmt, dann ist Either monad der richtige Weg .

+0

Danke für Ratschläge. – demas

Verwandte Themen