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

标签 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

没有括号,循环将不会终止。
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 

我很抱歉我不记得我在哪里看到了这个。我认为它在SO中。这是一个很好的例子。

这可能是没有括号我正在处理各种函数对象吗?

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

最佳答案

来自 C 系列语言(C#、Java、C、C++、JavaScript)的人似乎在理解 F# 中括号的使用方面存在问题。我当然有,而且我花了几年的时间来学习事情是如何运作的。

简而言之,F# 中最基本的构建 block 是值。值可以是 let -边界:

let foo = bar

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

函数也是值:
// 'a -> 'a * 'a
let f = fun x -> x, x

在这里,f是一个函数,它接受一些值( x )并返回一个带有 x 的元组作为第一个和第二个元素。

写起来有点麻烦,所以有一个简写:
// 'a -> 'a * 'a
let f x = x, x

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

有时您需要调整运算符的优先级。就像数学一样,1 + 2 * 3 (相当于 1 + (2 * 3) )与 (1 + 2) * 3 不同.在 F# 中,您还可以使用方括号来覆盖优先级。因此
// 'a -> string * 'a
let f x = someOtherFunction x, x

不一样
// x:'a -> string
let f x = someOtherFunction (x, x)

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

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

有时,您想定义一个不接受任何输入的函数。但是,您不能这样定义它:
let f = whatever

因为这会使它立即成为 let 的值-绑定(bind)到whatever .相反,您可以让函数采用内置类型 unit 的值。 .这种类型只有一个值,写成 () :
let f () = whatever

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

每当您调用 f() , 表达式 whatever被评估并返回。

关于f# - 为什么这个 F# 函数需要括号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39294881/

相关文章:

c++ - 与模板成员函数的接口(interface)

scala - 如何对 Set[ValidatedNel[String, Double]] 求和?

c# - WCF 性能、延迟和可伸缩性

f# - 声明变量而不分配

f# - 辅助GCD函数初学者

scala - 关于优化简单的 Scala FoldLeft 多个值的建议?

haskell - GHCi "let"——它有什么作用?

java - Java编译器中 "let expression"(LetExpr)的用途?

Elm:偏函数应用和 Let

.net - 在 F# 中从字符串中去除字符