没有分号的方括号是什么意思?

时间:2017-02-11 12:48:35

标签: f#

我在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" ]

2 个答案:

答案 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和一个表达式(字符串列表)的组合。

  1. 列出语法
  2. 通常,您只会生成一个列表,而不是键入,但您可以使用换行符或;分隔这些项目。所以这两个列表是等价的:

    ["a";"b";"c"]
    
    ["a"
     "b"
     "c"
    ]
    
    1. 列表总是渴望F#,但是seqs很懒。
    2. yield有点像C#中的return,它不返回单位,它返回一个值,特别是在序列中。
    3. 创建示例时,您将获得:

        

      评估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语句和字符串列表返回结果时都执行delayeddelayed |> Seq.toList

        

      评估eagerList
        val it:string list = [“I”; “上午”; “一个”; “急于”;   “列表”]

      总而言之,是的,通常在[]中你有一个列表,你可以用一个;或换行符分隔itenms。但是,该具体示例实际上并不是一个通常的列表,而是一个旨在演示如何延迟评估的表达式,并且它包含一个print语句和一个字符串列表。

      此外,;可用于分隔同一行的语句,例如 printfn "%A" "foo";printfn "%A" "bar"