上海企业网站建设公司,自己的网站是什么样子的,爱站网怎么打不开,网站功能模块介绍惰性求值惰性求值也叫按需调用#xff0c;是一个演算策略#xff0c;延迟一个表达式的演算#xff0c;直到需要用到演算值的时候再演算#xff0c;同时也避免了重复演算。惰性求值的好处包括#xff1a;避免不必要的计算#xff0c;提升性能。可以构造以构造一个无限的数…惰性求值 惰性求值也叫按需调用是一个演算策略延迟一个表达式的演算直到需要用到演算值的时候再演算同时也避免了重复演算。 惰性求值的好处包括 避免不必要的计算提升性能。 可以构造以构造一个无限的数据结构 可以定义控制流的抽象类。 惰性求值由于仅仅在需要的时候才求值所以它可以缩小内存的访问范围。但是惰性求值处理异常输入输出的时候却有困难因为代码操作的顺序无法得知惰性求值可能引起内存泄漏。 惰性求值和函数式编程关系密切。如果没有语言中没有副作用编译器或可以自由的选择表达式的演算顺序。F#允许函数有副作用所以在函数演算时编译器不可能自由选择因此可以说F#有严格的演算顺序是一个严格的语言。你仍然可以利用惰性求值但是必选显式表面哪些计算可以延迟也就是哪些按照惰性的方法来演算。 惰性求值的相对的就是及早求值Eager evaluation也称严格求值。 使用关键字lazy来延时计算延迟计算的表达式一直不演算直到显式的对其使用force函数。当force函数用于由于惰性表达式值就马上计算结果会被缓存起来。后面再调用force函数则返回这个缓存值即使可能引起异常。 下面的代码演示了惰性求值。 let lazyValue lazy ( 2 2 )
let actualValue Lazy.force lazyValue
printfn %i actualValue 第一行延迟计算了一个简单表达式下一行强制计算最终打印出值。 这个值被缓存了所以这个值仅在第一次强制惰性求值的时候计算这很容易演示如下 let lazySideEffect lazy( let temp 2 2printfn %i temptemp )
printfn Force value the first time:
let actualValue1 Lazy.force lazySideEffect
printfn Force value the second time:
let actualValue2 Lazy.force lazySideEffect 上例中强制计算2次值但是此副作用值发生一次。运行结果如下 惰性求值在操作集合的时候很有用惰性集合的概念就是集合中的元素仅在需要的时候才计算。一些集合类型也会缓存计算结果所以也不需要重复计算元素。 注意此处用 Lazy.force因为作者可能使用的OCaml在F#从 OCaml 风格转到C#风格之前。现在用x.Value 或者x.Force()替代。由于某些原因F#现在在PowerPack中。F# PowerPack是由微软的F#团队提供的编译器和核心库。http://fsharppowerpack.codeplex.com/ 创建惰性集合最重要也是最难的可能要数unfold。此函数允许你建立惰性List。难点在于你必须提供一个函数此函数用于重复计算以提供元素。这个传递给Seq.unfold的函数可以接受任何类型的参数并且必须返回一个option类型。option类型是一个union类型可以是None或者Some(x)x是任何类型的值。None代表list的结束。Some 结构必须包含一个元组。第一个元素是list中的第一个值第二个值是下一次调用的时候要传给函数的值。你可以认为这个值是一个累加器。 看一个例子就明白标识符lazyList如果传递给函数的值小于13追加到list然后把值加1传递给list。这个值将是下一次调用的时候传递给函数的。如果这个值大于等于12返回None终结这个list。 // the lazy list definition
let lazyList Seq.unfold(fun x -if x 13 then// if smaller than the limit return// the current and next valueSome(x, x 1)else// if great than the limit// terminate the sequenceNone)10
// print the results
printfn %A lazyList 结果就是 101112 Sequences用来表示list如果内存无限多那么也就可以有无限多元素。下面的例子演示创建一个Fibonacci数列。由于使用了bigint不受32-bit整型限制可以计算更多的数字。为了演示方便使用函数 Seq.take返回前20个元素到F#的list中。 // create an infinite list of Fibonacci numbers
let fibs Seq.unfold(fun (n0, n1) -Some(n0, (n1, n0 n1)))(1I,1I)
// take the first twenty items from the list
let first20 Seq.take 20 fibs
// print the finite list
printfn %A first20 计算结果 [1I; 1I; 2I; 3I; 5I; 8I; 13I; 21I; 34I; 55I; 89I; 144I; 233I; 377I; 610I; 987I; 1597I; 2584I; 4181I; 6765I]