我需要defaultArg
函数的实现,Lazy
作为第二个参数。这是一个用法示例:
defaultArgLazy option (lazy doSomeHeavyWorkThatShouldBeAvoided())
它很容易实现
let defaultArgLazy o (p:'a Lazy) =
match o with
| Some v -> v
| None -> p.Force()
但我想知道是否有一个我缺失的标准实施。
答案 0 :(得分:1)
我不知道内置的任何内容,但这是您的功能的更通用版本:
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
它需要(unit -> 'a)
的任何功能,而不是具体的Lazy<'a>'
,因此您只需通过Lazy的Force
方法,并保留评估仅发生的保证一次。
在.NET现有的Lazy.Force()
之上,可能会在F#中添加Lazy.Value
,以便您可以更高效地使用更高阶函数。
请注意,我已将参数顺序与内置defaultArg
进行交换,以便与其他模块中的函数更加一致,更方便管道/曲线。
答案 1 :(得分:1)
如果懒惰值仅在代码的稍后时间点使用,则使用defaultArg
并将Lazy<'a> option
作为第一个参数传递给它也可能是个主意。这样选择选项或默认参数就会与评估结果时分开。
采取这个想法,功能
let defaultArgLazy opt lazyDef =
(defaultArg (Option.map Lazy.CreateFromValue opt) lazyDef).Value
会做你想要的 - 就像TheQuickBrownFox那样。