What do square brackets without semicolons mean?

I found the code below in the book F# Design Patterns by Gene Belitski. I read about F #, but I did not find an explanation of this syntax in this book or elsewhere. I understand the yield keyword and what it does, and I know that the return values ​​of yield and printfn are of type one. I do not understand the square brackets. Operators are not separated by semicolons, as would be the case when creating a literal. It must be a special syntax, but I can not find links to it. Can anyone help?

 let eagerList = [ printfn "Evaluating eagerList" yield "I" yield "am" yield "an" yield "eager" yield "list" ] 
+6
source share
2 answers

This is actually a list comprehension or some kind of calculation expression. I think this example brings together several different things that are likely to confuse you, so maybe this book is actually not the best first or intro book for F #. If you read p. 169 carefully explains what it is. The author wants to demonstrate that with Seq.delay , you can defer a pending evaluation. If you first evaluate the list, it actually prints the “Evaluation of the desired list” part, but only when you create it. After that, this will not happen. You can see that printfn not on the list. This is more like an instruction, one printfn and an expression (list of lines).

  • List syntax

Usually you just create a list, not enter it, but you can split the elements with a new line or ; . So these two lists are equivalent:

 ["a";"b";"c"] ["a" "b" "c" ] 
  1. Lists are always impatient in F #, however seqs are lazy.
  2. yield is similar to return in C #, it does not return unit, it returns a value, especially in a sequence.

When you create an example, you get the following:

EagerList Score
val eagerList: string list = ["I"; "I AM" ; "AN"; "Impatient"; "List"]

So you can see that printfn not on the list.

If you run eagerList , you will only see:

val it: string list = ["I"; "I AM" ; "AN"; "Impatient"; "list"]

Confirmation of our suspicion.

Now, what Jean Belinitsky wanted to demonstrate was:

 let delayed = Seq.delay (fun _ -> ([ printfn "Evaluating eagerList" yield "I" yield "am" yield "an" yield "eager" yield "list" ] |> Seq.ofList)) 

val delayed: seq

Not only does it not print the list, it is not the event that printfn prints the statement! And this is seq, not a list.

If you do delayed or delayed |> Seq.toList every time you return the result from the printfn statement, as well as a list of lines:

EagerList Score
val it: string list = ["I"; "I AM" ; "AN"; "Impatient"; "List"]

So, to summarize, yes, usually in [] you have a list, and you either separate itenms with ; , or a new line. However, this specific example is not really an ordinary list, but an expression designed to demonstrate how you can defer evaluation, and for this it contains a print statement as well as a list of lines.

Also ; can be used to separate statements on one line, for example. printfn "%A" "foo";printfn "%A" "bar"

+3
source

This is a list.

You can define a list by explicitly specifying elements separated by semicolons and enclosed in square brackets.

  let eagerList = [ printfn "Evaluating eagerList"; yield "I"; yield "am"; yield "an"; yield "eager"; yield "list" ] 

You can also put line breaks between elements, in which case semicolons are optional. The latter syntax can lead to more readable code when element initialization expressions are longer or when you want to include a comment for each element.

 let eagerList = [ printfn "Evaluating eagerList" yield "I" yield "am" yield "an" yield "eager" yield "list" ] 

Both of these codes do the same.
Note that the second snippet could be written in the same way, since semicolons are optional if you put line breaks between elements.

 let eagerList = [ printfn "Evaluating eagerList"; yield "I"; yield "am"; yield "an"; yield "eager"; yield "list"; ] 

Mark it.

+7
source

Source: https://habr.com/ru/post/1014899/


All Articles