gpt4 book ai didi

来自流阅读器的 F# 懒惰评估?

转载 作者:行者123 更新时间:2023-12-04 17:05:08 24 4
gpt4 key购买 nike

我在我的代码中遇到了一个错误,这让我觉得我并不真正了解有关 F# 和惰性求值的一些细节。我知道 F# 会急切地求值,因此对以下函数有些困惑:

// Open a file, then read from it. Close the file. return the data.
let getStringFromFile =
File.OpenRead("c:\\eo\\raw.txt")
|> fun s -> let r = new StreamReader(s)
let data = r.ReadToEnd
r.Close()
s.Close()
data

当我在 FSI 中调用它时:
> let d = getStringFromFile();;

System.ObjectDisposedException: Cannot read from a closed TextReader.

at System.IO.__Error.ReaderClosed()
at System.IO.StreamReader.ReadToEnd()
at <StartupCode$FSI_0134>.$FSI_0134.main@()
Stopped due to error

这让我觉得 getStringFromFile被懒惰地评估 - 所以我完全困惑。我没有得到有关 F# 如何评估函数的信息。

最佳答案

为了快速解释发生了什么,让我们从这里开始:

let getStringFromFile =  
File.OpenRead("c:\\eo\\raw.txt")
|> fun s -> let r = new StreamReader(s)
let data = r.ReadToEnd
r.Close()
s.Close()
data

您可以将函数的前两行重写为:
let s = File.OpenRead(@"c:\eo\raw.txt")

接下来,您省略了此方法的括号:
            let data = r.ReadToEnd
r.Close()
s.Close()
data

结果, data有类型 unit -> string .当你从你的函数返回这个值时,整个结果是 unit -> string .但是看看在分配变量和返回变量之间发生了什么:你关闭了流。

最终结果,当用户调用该函数时,流已经关闭,导致您在上面看到的错误。

并且不要忘记通过声明 use whatever = ... 来处理您的对象而不是 let whatever = ... .

考虑到这一点,这里有一个修复:
let getStringFromFile() =  
use s = File.OpenRead(@"c:\eo\raw.txt")
use r = new StreamReader(s)
r.ReadToEnd()

关于来自流阅读器的 F# 懒惰评估?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3720141/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com