2016-09-02 3 views
5

Зачем нужны скобки на read_rest_of_csv?Зачем нужны скобки для этой функции F #?

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. Это хороший пример.

Возможно ли это, что без parens я имею дело с функциональным объектом?

Я действительно исхожу из не только C, C++ и C# фона, но также и промежуточного фона Clojure. В моем случае с синтаксисом F # чтение моего руководства Haskell в несколько более подробной информации могло бы помочь, потому что синтаксисы кажутся похожими.

ответ

18

Похоже, что люди, идущие из языков C-семейства (C#, Java, C, C++, JavaScript), сталкиваются с трудностями при понимании использования скобок в F #. Я, конечно, был, и мне потребовалось несколько лет, чтобы узнать, как все работает.

Вкратце, самый основной строительный блок в F # является значением . Значения могут быть 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 -связанного к whatever. Вместо этого вы можете позволить функции принимать значение встроенного типа unit. Этот тип имеет только одно значение, которое записывается ():

let f() = whatever 

Это означает, что f является функцией, которая шаблон соответствует его вход против единственной известной величины unit.

Всякий раз, когда вы вызываете f с (), вычисляется и возвращается выражение whatever.

+0

Вы сделали хороший вывод о том, что люди программируют фон, идущий на F #. Итак, я добавил еще кое-что в OP, чтобы указать мой фон. Часть, которую мне нужно будет использовать, - это такие вещи, как unit,() и те привязки. – octopusgrabbus

5

Без круглых скобок содержание выполняется один раз и никогда больше. read_rest_of_csv имеет тип bool: В основном вы говорите while true do ignore None.

Скобки указывают, что read_rest_of_csv имеет тип unit -> bool, поэтому каждый раз, когда вы вызываете его, он считывает строку и перемещает курсор. В противном случае это будет сделано только один раз.

+0

Могу ли я использовать скобки вместо parens? – octopusgrabbus

+0

Для «скобок» читайте «круглые скобки». Боюсь, я отредактирую свой ответ (а не с детьми). –

+0

Благодаря RobLyndon – octopusgrabbus

3

Ответ на ваш вопрос в том, что:

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

не является функцией на всех. Это ничем не отличается от:

> let i = 1;; 

val i : int = 1 

Это объявляет привязку с целым значением. Если вы хотите объявить привязку со значением функции, которая не принимает никаких параметров, который выглядит следующим образом:

> let i() = 1;; 

val i : unit -> int 

Точно такая же логика применима к read_rest_of_csv. Без скобок вы объявляете привязку с типом bool. В скобках вы объявляете привязку с типом unit->bool, то есть привязкой со значением функции, где функция не принимает никаких входов и возвращает значение bool.

Смежные вопросы