为什么此 F# 函数需要括号? [英] Why are parentheses needed on this F# function?

查看:36
本文介绍了为什么此 F# 函数需要括号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么下面的 read_rest_of_csv 需要括号?

Why are parentheses 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 the parentheses, the loop will not terminate.

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 中.这是一个很好的例子.

I apologize that I cannot remember where I saw this. I think it was in SO. It's a nice example.

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

Could this be that without parens I'm dealing with a function object of sorts?

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

I am indeed coming from not only a C, C++, and C# background, but also an intermediate Clojure background as well. In my case with F# syntax, reading my Haskell manual in a little more detail might have helped, because the syntaxes seem similar.

推荐答案

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

It seems that people coming from C-family languages (C#, Java, C, C++, JavaScript) are having problems understanding the use of brackets in F#. I certainly had, and it took me some years learning how things work.

简而言之,F# 中最基本的构建块是.值可以被 let 绑定:

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

let foo = bar

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

This means that foo is a value, which happens to be equal to bar.

函数也是值:

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

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

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

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

That's a bit cumbersome to write, so there's a shorthand for that:

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

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

Notice that there are no brackets in these expressions.

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

Sometimes you need to adjust the precedence of operators. Just like in maths, 1 + 2 * 3 (which is equivalent to 1 + (2 * 3)) isn't the same as (1 + 2) * 3. In F#, you also use brackets to override precedence. Thus

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

不一样

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

(在本例中,someOtherFunction 是一个返回 string 的函数.)

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

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

Notice that the brackets don't denote a function call; they're only there to control order of evaluation.

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

Sometimes, you want to define a function that doesn't take any input. You can't, however, define it like this:

let f = whatever

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

because that would make it a value that's immediately let-bound to whatever. Instead, you can let the function take a value of the built-in type unit. This type only has a single value, which is written ():

let f () = whatever

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

This means that f is a function that pattern matches its input against the only known value of unit.

每当您使用 () 调用 f 时,都会计算并返回表达式 whatever.

Whenever you invoke f with (), the expression whatever is evaluated and returned.

这篇关于为什么此 F# 函数需要括号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆