Why do you need parentheses for this F # function?

Why are brackets needed on read_rest_of_csv below?

  let read_rest_of_csv() = csv_data.Add(csv_fileH.ReadFields()) |> ignore not csv_fileH.EndOfData while read_rest_of_csv() do ignore None 

Without parentheses, the loop will not end.

 open System open System.Threading open System.Collections.Generic open System.Linq open System.Text open System.Threading.Tasks open System.IO open Microsoft.VisualBasic.FileIO [<EntryPoint>] let main argv = let csv_fileH = new TextFieldParser("test1.csv") csv_fileH.TextFieldType = FieldType.Delimited |> ignore let x = csv_fileH.SetDelimiters(",") let csv_data = new List<string[]>() let eod = csv_fileH.EndOfData if not eod then let column_headings = csv_fileH.ReadFields() csv_data.Add(column_headings) |> ignore let read_rest_of_csv = csv_data.Add(csv_fileH.ReadFields()) |> ignore not csv_fileH.EndOfData while read_rest_of_csv do ignore None 0 

I apologize for not being able to remember where I saw this. I think it was in SO. This is a good example.

Could it be that without parens I am dealing with a functional object of the kind?

I really come from not only C, C ++ and C # backgrounds, but also Clojure's intermediate background. In my case with F # syntax, reading my Haskell tutorial in a bit more detailed information might help, because the syntaxes seem similar.

+5
source share
3 answers

It seems that people coming from languages ​​of the C-family (C #, Java, C, C ++, JavaScript) are faced with problems understanding the use of parentheses in F #. Of course, I was, and it took me several years to find out how everything works.

In short, the most basic building block in F # is value. Values ​​can be let -bound:

 let foo = bar 

This means that foo is a value that turns out to be equal to bar .

Functions are also values:

 // 'a -> 'a * 'a let f = fun x -> x, x 

Here f is a function that takes some value ( x ) and returns a tuple with x both the first and second element.

It's a little cumbersome to write, so there is a shortcut for this:

 // 'a -> 'a * 'a let fx = x, x 

Note that there are no parentheses in these expressions.

Sometimes you need to prioritize operators. As in mathematics, 1 + 2 * 3 (which is equivalent to 1 + (2 * 3) ) does not coincide with (1 + 2) * 3 . In F #, you also use parentheses to override priority. In this way,

 // 'a -> string * 'a let fx = someOtherFunction x, x 

does not match

 // x:'a -> string let fx = someOtherFunction (x, x) 

(in this case, someOtherFunction is a function that returns a string .)

Note that parentheses do not indicate a function call; they are only there to control the evaluation order.

Sometimes you want to define a function that does not accept any data. However, you cannot define it like this:

 let f = whatever 

because it will make it a value that immediately let -bound on whatever . Instead, you can let the function accept the value of the built-in type unit . This type has only one value, which is written () :

 let f () = whatever 

This means that f is a function that corresponds to its entry against the only known unit value.

Whenever you call f with () , the expression whatever evaluates to and returns.

+19
source

Without parentheses, the content is executed once and never again. read_rest_of_csv is of type bool : you basically say while true do ignore None .

The brackets indicate that read_rest_of_csv is of type unit -> bool , so every time you call it, it reads a line and moves the cursor. Otherwise, it will be done only once.

+5
source

The answer to your question:

 let read_rest_of_csv = csv_data.Add(csv_fileH.ReadFields()) |> ignore not csv_fileH.EndOfData 

not a function at all. This is no different from:

 > let i = 1;; val i : int = 1 

Declares a binding with an integer value. If you want to declare a binding with a function value that takes no parameters, it looks like this:

 > let i () = 1;; val i : unit -> int 

The same goes for read_rest_of_csv . Without a parenthesis, you declare a binding with type bool . In parentheses, you declare a binding with the type unit->bool ie binding to the value of the function, where the function does not accept any inputs and returns the value bool.

+3
source

All Articles