Scott Nimrod
Scott Nimrod

Reputation: 11595

What does the use of brackets really mean in F#?

I need help understanding the following statement:

let dictionary = [ for i in 1..4 -> i, true ] |> Map.ofSeq

Specifically, I am confused about the rules regarding the use of brackets.

  1. What does the use of brackets really mean in F#?
  2. What type of collection/set do brackets enclose? (i.e. array, seq, list, etc.)
  3. Can any expression that returns a collection be used within brackets?

NOTE

I know nothing about F#. So please forgive my ignorance.

Upvotes: 1

Views: 805

Answers (3)

Helge Rene Urholm
Helge Rene Urholm

Reputation: 1188

Just break it up.

let step1 = [ for i in 1..4 -> i, true ]
let step2 = step1 |> Map.ofSeq

Then you may be able to read the "signatures" of each step:

val step1 : (int * bool) list = [(1, true); (2, true); (3, true); (4, true)]
val step2 : Map<int,bool> = map [(1, true); (2, true); (3, true); (4, true)]

step1 is then a list so the brackets are for list (list expression). Inside the list there is a tuple (algebraic data type, product type) of int and bool (int * bool) (note the * for 'product').

step2 is a Map, created from a sequence, and a list is also a sequence so that is the reason why that works (or lists supports the sequence interface). ofSeq should be the total giveaway I would guess.

Using Map.ofList would probably make it less confusing, but its equivalent

let step1 = [ for i in 1..4 -> i, true ]
let step2 = step1 |> Map.ofList 

val step1 : (int * bool) list = [(1, true); (2, true); (3, true); (4, true)]
val step2 : Map<int,bool> = map [(1, true); (2, true); (3, true); (4, true)]

You may benefit from reading some documentation like: https://msdn.microsoft.com/en-us/library/dd233230.aspx

Now send me my certificate from this course of yours... ;-)

Upvotes: 2

Functional_S
Functional_S

Reputation: 1159

These are the used brackets in F#

()

(1, 2)                      // Tuple (separator is a comma)
()                          // empty tuple, called unit

[]

[  1; 2  ]                  // List
[]                          // List.empty 

[| 1; 2 |]                  // Array
[||]                        //  Array.empty

{}

seq { yield 1; yield 2  }   // Sequence
Seq.empty                   // empty Sequence, not {} 

async { return 1 }          // Computation Expressions, e.g. async

type record =               // Record type definition
    { Name : string 
      Age  : int
    }

<>

type A<'T> = A of 'T              

Types can easily be composed

let composition = 
    async { return
                [| 
                    [ ("A",1); ("B",2) ]
                    [ ("C",3) ] 
                |]
    }
// val composition : Async<(string * int) list []>

Upvotes: 5

Richard
Richard

Reputation: 108975

[ sequence-expression ]

Creates a List

Other types of brackets create different types of collections eg. seq { ... } or \[| sequence-expression |\] for sequences (IEnumerable<T>) or arrays respectively.

Can any expression that returns a collection be used within brackets?

Sort of. There is a whole load of support for creating various collections (eg. yield value) including also merging sub-collections (yield! expression).

Really too much for a quick answer. The links about into the F# Reference will show you the scope of this.

Upvotes: 1

Related Questions