我在Gene Belitski的书F# Design Patterns
中找到了以下代码。我一直在阅读有关F#的内容,但我还没有在该书或其他地方找到这种语法的解释。我理解关键字yield
及其作用,我知道yield和printfn语句的返回值都是unit类型。我不明白的是方括号。这些语句不像分号创建那样用分号分隔。这必须是一个特殊的语法,但我找不到它的引用。有人可以帮忙吗?
let eagerList = [
printfn "Evaluating eagerList"
yield "I"
yield "am"
yield "an"
yield "eager"
yield "list" ]
答案 0 :(得分:7)
这是一个清单。
您可以通过明确列出元素来定义列表,以分号分隔并用方括号括起来。
let eagerList = [ printfn "Evaluating eagerList"; yield "I"; yield "am"; yield "an"; yield "eager"; yield "list" ]
您还可以在元素之间放置换行符,在这种情况下,分号是可选的。当元素初始化表达式较长时,或者当您想要为每个元素包含注释时,后一种语法可以使代码更易读。
let eagerList = [
printfn "Evaluating eagerList"
yield "I"
yield "am"
yield "an"
yield "eager"
yield "list" ]
这两个代码完全相同。
注意,第二个代码段也可能是这样编写的,因为如果在元素之间放置换行符,分号是可选的。
let eagerList = [
printfn "Evaluating eagerList";
yield "I";
yield "am";
yield "an";
yield "eager";
yield "list"; ]
查看this.
答案 1 :(得分:3)
这实际上是列表理解或某种计算表达式。我认为这个例子混淆了一些可能让你感到困惑的不同事情,所以也许这本书实际上并不是F#最好的第一本书或介绍书。如果你读过p。尽管如此,它还是仔细地解释了它的全部意义。作者希望用Seq.delay
证明这一点,你可以推迟热切的评估。如果您首先评估列表,它实际上会打印“评估热切列表”部分,但仅在您创建它时。之后它不会。您可以看到printfn
不属于列表。所以它更像是一个语句,一个printfn和一个表达式(字符串列表)的组合。
通常,您只会生成一个列表,而不是键入,但您可以使用换行符或;
分隔这些项目。所以这两个列表是等价的:
["a";"b";"c"]
["a"
"b"
"c"
]
yield
有点像C#中的return
,它不返回单位,它返回一个值,特别是在序列中。 创建示例时,您将获得:
评估eagerList
val eagerList:string list = [“I”; “上午”; “一个”; “急于”; “列表”]
因此,您可以看到printfn
不属于列表。
如果您运行eagerList
,则只会看到:
val it:string list = [“I”; “上午”; “一个”; “急于”; “list”]
确认我们的怀疑。
Gene Belinitsky想要展示的是:
let delayed = Seq.delay (fun _ -> ([
printfn "Evaluating eagerList"
yield "I"
yield "am"
yield "an"
yield "eager"
yield "list" ] |> Seq.ofList))
val延迟:seq
不仅没有打印出列表,它还没有事件打印出printfn语句!这是一个seq,而不是列表。
如果每次从printfn语句和字符串列表返回结果时都执行delayed
或delayed |> Seq.toList
:
评估eagerList
val it:string list = [“I”; “上午”; “一个”; “急于”; “列表”]
总而言之,是的,通常在[]中你有一个列表,你可以用一个;
或换行符分隔itenms。但是,该具体示例实际上并不是一个通常的列表,而是一个旨在演示如何延迟评估的表达式,并且它包含一个print语句和一个字符串列表。
此外,;
可用于分隔同一行的语句,例如
printfn "%A" "foo";printfn "%A" "bar"