F#如何保留延迟/复制非强制惰性语句

问题描述 投票:1回答:1

下面的输出是15,9,9但是我想要15,9,21我想保留一个懒惰的版本,所以我可以在一个组合函数中放入一个新的函数版本。

open System
let mutable add2  = fun x-> x+2
let mutable mult3 = fun x-> x*3
let mutable co = add2 >> mult3
let mutable com = lazy( add2 >> mult3)
let mutable com2 = com

add2<- fun x-> x
co 3|> printfn "%A"
com.Force() 3|> printfn "%A"
add2<- fun x-> x+4
com2.Force() 3|> printfn "%A"
f# lazy-evaluation
1个回答
1
投票

我不认为你在这里需要延迟值 - 懒惰值在需要时被评估一次,但之后它的值不会改变。在您的情况下,您需要Force重新评估值,以防某些依赖项发生更改。你可以定义这样的东西:

type Delayed<'T> = 
  | Delayed of (unit -> 'T)
  member x.Force() = let (Delayed f) = x in f()

let delay f = Delayed f

这表示使用Force方法的延迟值(实际上只是一个函数),每次访问时都会对其进行评估。如果您使用delay重写代码,它的行为符合您的要求:

let mutable add2 = fun x-> x+2
let mutable mult3 = fun x-> x*3
let mutable com = delay(fun () -> add2 >> mult3)
let mutable com2 = com

add2 <- fun x -> x
com.Force() 3 |> printfn "%A"
add2 <- fun x -> x + 4
com2.Force() 3 |> printfn "%A"

与懒惰不同,这不会进行任何缓存,因此两次调用Force只会完成整个事情两次。您可以通过跟踪计算的依赖关系图来添加一些缓存,但它会变得更复杂。

© www.soinside.com 2019 - 2024. All rights reserved.