包含列表理解的嵌套函数

Nested function containing list comprehension

我可以有这样的功能:

let readLines (filePath:string) = [
    use sr = new StreamReader (filePath)
    while not sr.EndOfStream do
        yield sr.ReadLine ()
]

但是我不能有这样的功能:

let lines (f:string) =
    let readLines (filePath:string) = [
        use sr = new StreamReader (filePath)
        while not sr.EndOfStream do
            yield sr.ReadLine ()
    ] in readLines f

我收到错误:

Block following this 'let' is unfinished. Expect an expression. 

我无法解决这个错误。我希望有一个来自 'lines'.

的字符串列表

使您的第二个代码段编译的最小更改是在结束方括号之前再插入两个(或一个)space:

let lines (f:string) =
    let readLines (filePath:string) = [
        use sr = new StreamReader (filePath)
        while not sr.EndOfStream do
            yield sr.ReadLine ()
      ] in readLines f

原因是 let 绑定的主体需要比 let 关键字进一步缩进 - F# 编译器使用它来确定函数主体表达式的结束位置。这也是错误消息试图说的 "this 'let' is unfinished" 几乎总是意味着您在 let.

中没有有效的表达式

正如@kvb 在评论中提到的,一种更惯用的写法是完全依赖 F# 编译器是白色 space 敏感的事实,并将推断 in关键字在正确缩进的代码中。我个人的偏好是也将 [ 换行:

let lines (f:string) =
    let readLines (filePath:string) = 
      [ use sr = new StreamReader (filePath)
        while not sr.EndOfStream do
            yield sr.ReadLine () ]
    readLines f