为什么这个F#函数需要括号?

oct*_*bus 8 f# functional-programming let

为什么read_rest_of_csv下面需要括号?

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

    while read_rest_of_csv() do ignore None
Run Code Online (Sandbox Code Playgroud)

如果没有括号,循环将不会终止.

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 
Run Code Online (Sandbox Code Playgroud)

我道歉,我不记得我在哪看到这个.我认为这是在SO.这是一个很好的例子.

这可能是没有parens我正在处理各种各样的功能对象?

我确实不仅来自C,C++和C#背景,还来自中间Clojure背景.在我使用F#语法的情况下,更详细地阅读我的Haskell手册可能会有所帮助,因为语法看起来很相似.

Mar*_*ann 25

似乎来自C系列语言(C#,Java,C,C++,JavaScript)的人在理解F#中括号的使用时遇到了问题.我当然有,并且花了几年时间学习如何运作.

简而言之,F#中最基本的构建块是一个.值可以是let-bound:

let foo = bar
Run Code Online (Sandbox Code Playgroud)

这意味着这foo是一个恰好等于的值bar.

功能也是值:

// 'a -> 'a * 'a
let f = fun x -> x, x
Run Code Online (Sandbox Code Playgroud)

这里f是一个函数,它接受一些value(x)并返回一个元组x作为第一个和第二个元素.

这写起来有点麻烦,所以有一个简写:

// 'a -> 'a * 'a
let f x = x, x
Run Code Online (Sandbox Code Playgroud)

请注意,这些表达式中没有括号.

有时您需要调整运算符的优先级.就像在数学中一样,1 + 2 * 3(相当于1 + (2 * 3))也不一样(1 + 2) * 3.在F#中,您还使用括号来覆盖优先级.从而

// 'a -> string * 'a
let f x = someOtherFunction x, x
Run Code Online (Sandbox Code Playgroud)

是不一样的

// x:'a -> string
let f x = someOtherFunction (x, x)
Run Code Online (Sandbox Code Playgroud)

(在这种情况下,someOtherFunction是一个返回a string.的函数.)

请注意,括号不表示函数调用; 他们只是为了控制评估的顺序.

有时,您希望定义一个不接受任何输入的函数.但是,您不能像这样定义它:

let f = whatever
Run Code Online (Sandbox Code Playgroud)

因为这会使它成为一个立即绑定的.相反,您可以让函数采用内置类型的值.此类型只有一个值,写入:letwhateverunit()

let f () = whatever
Run Code Online (Sandbox Code Playgroud)

这意味着这f是一个模式将其输入与唯一已知值匹配的函数unit.

每次调用f(),表达whatever进行评估并返回.


Rob*_*don 6

如果没有括号,内容将执行一次,而不会再次执行.read_rest_of_csv有一种类型bool:你基本上是在说while true do ignore None.

括号表示read_rest_of_csv有类型unit -> bool,因此每次调用它时,它都会读取一行并移动光标.否则,它只会执行一次.