2016-04-30 6 views
5

Ich brauche eine Implementierung von defaultArg Funktion mit Lazy als zweiten Parameter. Hier ist ein Anwendungsbeispiel:Gibt es eine Standardimplementierung von F # defaultArg akzeptieren faul?

defaultArgLazy option (lazy doSomeHeavyWorkThatShouldBeAvoided()) 

Es ist ganz einfach

let defaultArgLazy o (p:'a Lazy) = 
    match o with 
    | Some v -> v 
    | None -> p.Force() 

zu implementieren, aber ich frage mich, ob es eine Standard-Implementierung ist, dass ich fehle.

+0

Nein, es gibt keinen Standard dafür. – scrwtp

Antwort

1

Ich weiß nicht von irgendetwas gebaut, aber hier ist eine allgemeinere Version Ihrer Funktion:

module Option = 
    let lazyDefault f opt = 
     match opt with 
     | Some x -> x 
     | None -> f() 

let lazyVal = lazy 1 
let opt = None 

opt |> Option.lazyDefault lazyVal.Force // returns 1 

Es nimmt jede Funktion von (unit -> 'a) statt speziell ein Lazy<'a>', so dass Sie nur durch faulen Pass Force Methode und behalten die Garantie, dass die Auswertung nur einmal erfolgt.

Vielleicht Lazy.Force() wurde in F # auf der vorhandenen .NET Lazy.Value hinzugefügt, so dass Sie es idiomatisch mit Funktionen höherer Ordnung verwenden können.

Beachten Sie, dass ich die Parameterreihenfolge im Vergleich zu den integrierten defaultArg vertauscht habe, um konsistenter mit Funktionen in anderen Modulen zu werden und für das Piping/Curry-Verfahren.

1

Wenn der Lazy-Wert nur zu einem späteren Zeitpunkt im Code verwendet wird, könnte es auch eine Idee sein, defaultArg zu verwenden und als erstes Argument eine Lazy<'a> option zu übergeben. Auf diese Weise wird die Auswahl der Option oder des Standardarguments von der Auswertung des Ergebnisses getrennt.

Unter dieser Idee, die Funktion

let defaultArgLazy opt lazyDef = 
    (defaultArg (Option.map Lazy.CreateFromValue opt) lazyDef).Value 

tun würde, was Sie wollen - wie die von TheQuickBrownFox tut.

Verwandte Themen