2016-04-30 5 views
5

Ho bisogno di un'implementazione della funzione defaultArg con Lazy come secondo parametro. Ecco un esempio di utilizzo:Esiste un'implementazione standard di F # defaultArg che accetta pigro?

defaultArgLazy option (lazy doSomeHeavyWorkThatShouldBeAvoided()) 

E 'abbastanza facile da implementare

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

ma mi chiedo se c'è un'implementazione standard che mi manca.

+0

No, non c'è niente di standard per quello. – scrwtp

risposta

1

non so di nulla integrato, ma ecco una versione più generale della funzione:

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 

Prende qualsiasi funzione di (unit -> 'a) invece di specificamente un Lazy<'a>', quindi basta passare attraverso pigro di Force metodo, invece, e mantenere la garanzia che la valutazione avvenga solo una volta.

Forse è stato aggiunto in F # sopra a .NET esistente Lazy.Value in modo da poterlo utilizzare in modo più idiomatico con funzioni di ordine superiore.

Nota che ho scambiato l'ordine dei parametri rispetto allo defaultArg integrato per essere più coerente con le funzioni in altri moduli e più conveniente per piping/currying.

1

Se il valore lazy viene utilizzato solo in un momento successivo nel codice, potrebbe essere anche un'idea utilizzare defaultArg e passarlo a Lazy<'a> option come primo argomento. In questo modo, la scelta dell'opzione o dell'argomento predefinito viene separata da quando viene valutato il risultato.

Alla luce di questa idea, la funzione

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

sarebbe fare quello che vuoi - come fa l'uno per TheQuickBrownFox.

Problemi correlati