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

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

问题描述

为什么在 read_rest_of_csv 下需要括号?

  let read_rest_of_csv()= 
csv_data.Add(csv_fileH.ReadFields())|>忽略
而不是csv_fileH.EndOfData

while read_rest_of_csv()do ignore None



 打开系统
打开System.Threading
打开System.Collections.Generic
打开System.Linq
打开System.Text
打开System.Threading.Tasks
打开System.IO
打开Microsoft.VisualBasic。 FileIO

[< EntryPoint>]
let main argv =
let csv_fileH = new TextFieldParser(test1.csv)
csv_fileH.TextFieldType = FieldType.Delimited |>忽略
let x = csv_fileH.SetDelimiters(,)
let csv_data = new List< string []>()

let eod = csv_fileH.EndOfData
如果不是eod,则
让column_headings = csv_fileH.ReadFields()
csv_data.Add(column_headings)|>忽略

让read_rest_of_csv =
csv_data.Add(csv_fileH.ReadFields())|>忽略
而不是csv_fileH.EndOfData

,而read_rest_of_csv忽略无

0

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



难道这是没有parens我正在处理一个函数对象的类?

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

解决方案

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

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

  let foo = bar 

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



函数也是值:

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

这里, f 是一个函数需要一些值( x ),并返回一个元组作为第一个元素和第二个元素< x 。 / b>

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

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

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



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

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

不一样

  // x:'a  - >字符串
让fx = someOtherFunction(x,x)

(在这种情况下, someOtherFunction 是一个函数,它返回一个字符串。)



括号不表示函数调用;他们只是在那里控制评估的顺序。



有时候,你想要定义一个没有任何输入的函数。然而,你不能这样定义它:

  let f = whatever 

因为这会使它成为一个,它立即 let - 绑定到任何。相反,您可以让函数获取内置类型 unit 的值。这种类型只有一个值,写成()

  let f()= whatever 

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



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


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 

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?

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.

解决方案

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.

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

let foo = bar

This means that foo is a value, which happens 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 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.

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

isn't the same as

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

(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

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

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

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

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

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