为什么迭代先前读入的序列会触发新的读取?
Why does iterating previously read-in sequence trigger a new read?
在此 SO post 中,添加
inSeq
|> Seq.length
|> printfn "%d lines read"
导致 inSeq 中的惰性序列被读入。
好的,我已经扩展了该代码并希望首先打印出该序列(请参阅下面的新程序)。
当 Visual Studio (2012) 调试器到达
inSeq |> Seq.iter (fun x -> printfn "%A" x)
读取过程重新开始。当我使用调试器检查 inSeq
时,inSeq
似乎没有任何元素。
如果我先将元素读入 inSeq
,我如何才能看到(检查)这些元素,为什么它们不会通过调用 Seq.iter
打印出来?
open System
open System.Collections.Generic
open System.Text
open System.IO
#nowarn "40"
let rec readlines () =
seq {
let line = Console.ReadLine()
if not (line.Equals("")) then
yield line
yield! readlines ()
}
[<EntryPoint>]
let main argv =
let inSeq = readlines ()
inSeq
|> Seq.length
|> printfn "%d lines read"
inSeq |> Seq.iter (fun x -> printfn "%A" x)
// This will keep it alive enough to read your output
Console.ReadKey() |> ignore
0
我在某处读到惰性求值的结果没有被缓存。这就是这里发生的事情吗?如何缓存结果?
序列不是 "container" 项,而是 "promise" 在将来某个时间交付项。您可以将其视为您调用的一个函数,除了它 return 它的结果是分块的,而不是一次全部。如果您调用该函数一次,它会 return 给您一次结果。如果你第二次调用它,它将 return 第二次的结果。
因为你的特定序列不是纯的,你可以把它比作一个非纯函数:你调用它一次,它return就是一个结果;你第二次调用它,它可能 return 不一样。
序列在第一次读取后不会自动 "remember" 它们的项目 - 与函数在第一次调用后不会自动 "remember" 它们的结果完全相同。如果你想从一个函数中得到它,你可以把它包装在一个特殊的 "caching" 包装器中。所以你也可以为一个序列做。
"caching return value"的通用技术通常称为“memoization". For F# sequences in particular, it is implemented in the Seq.cache
函数。
在此 SO post 中,添加
inSeq
|> Seq.length
|> printfn "%d lines read"
导致 inSeq 中的惰性序列被读入。
好的,我已经扩展了该代码并希望首先打印出该序列(请参阅下面的新程序)。
当 Visual Studio (2012) 调试器到达
inSeq |> Seq.iter (fun x -> printfn "%A" x)
读取过程重新开始。当我使用调试器检查 inSeq
时,inSeq
似乎没有任何元素。
如果我先将元素读入 inSeq
,我如何才能看到(检查)这些元素,为什么它们不会通过调用 Seq.iter
打印出来?
open System
open System.Collections.Generic
open System.Text
open System.IO
#nowarn "40"
let rec readlines () =
seq {
let line = Console.ReadLine()
if not (line.Equals("")) then
yield line
yield! readlines ()
}
[<EntryPoint>]
let main argv =
let inSeq = readlines ()
inSeq
|> Seq.length
|> printfn "%d lines read"
inSeq |> Seq.iter (fun x -> printfn "%A" x)
// This will keep it alive enough to read your output
Console.ReadKey() |> ignore
0
我在某处读到惰性求值的结果没有被缓存。这就是这里发生的事情吗?如何缓存结果?
序列不是 "container" 项,而是 "promise" 在将来某个时间交付项。您可以将其视为您调用的一个函数,除了它 return 它的结果是分块的,而不是一次全部。如果您调用该函数一次,它会 return 给您一次结果。如果你第二次调用它,它将 return 第二次的结果。
因为你的特定序列不是纯的,你可以把它比作一个非纯函数:你调用它一次,它return就是一个结果;你第二次调用它,它可能 return 不一样。
序列在第一次读取后不会自动 "remember" 它们的项目 - 与函数在第一次调用后不会自动 "remember" 它们的结果完全相同。如果你想从一个函数中得到它,你可以把它包装在一个特殊的 "caching" 包装器中。所以你也可以为一个序列做。
"caching return value"的通用技术通常称为“memoization". For F# sequences in particular, it is implemented in the Seq.cache
函数。