2016-09-02 14 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 

私はこれを見たところ、私は覚えていないことをお詫び申し上げます。私はそうだったと思う。それは良い例です。

これは括弧なしで、私は関数オブジェクトを扱っていますか?

私は確かにC、C++、C#のバックグラウンドだけでなく、中間的なClojureバックグラウンドも持っています。私の場合、F#の構文では、構文が似ているように見えるので、少し詳細に私のHaskellのマニュアルを読むのが助けになるかもしれません。

答えて

18

Cファミリーの言語(C#、Java、C、C++、JavaScript)から来ている人は、F#の角括弧の使用を理解する上で問題があるようです。私は確かに持っていました。

F#の最も基本的なビルディングブロックは、という値です。

let foo = bar 

これはfoobarに等しくなるようにたまたま値であることを意味する:値はlet結合型であることができます。

も機能する値である:ここ

// '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 

ブラケット機能を示すものではない

注意(この場合、someOtherFunctionstringを返す関数である。)

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

と同じではありませんコール;彼らは評価の順序を制御するためだけにある。

入力を受け付けない関数を定義することがあります。それはそれすぐlet結合型whateverにだになるだろうので

let f = whatever 

:あなたは、しかし、このようにそれを定義することはできません。代わりに、関数に組み込み型unitの値を使用させることができます。

let f() = whatever 

これはfパターンunitの唯一の既知の値に対してその入力に一致する関数であることを意味する:このタイプは、()書き込まれる単一の値を有します。

()fを呼び出すと、式whateverが評価されて返されます。

+0

あなたはF#に来る人々のプログラミングの背景に関する良い点を作った。だから、自分の背景を示すためにOPにいくつか追加しました。私が使用しなければならない部分は、ユニット、()、それらのバインディングのようなものです。 – octopusgrabbus

5

括弧を付けないと、内容は一度だけ実行され、もう一度実行されません。 read_rest_of_csvのタイプはboolです。基本的にはwhile true do ignore Noneです。

括弧は、read_rest_of_csvがタイプunit -> boolであることを示しているため、呼び出すたびに行を読み取り、カーソルを移動します。それ以外の場合は、これは1回だけ行います。

+0

括弧の代わりに角かっこを使用できますか? – 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 : unit -> int 

まったく同じ論法がread_rest_of_csvに適用されます。かっこがなければ、タイプboolのバインディングを宣言しています。括弧を使用すると、タイプunit->boolのバインディング、つまりファンクション値を持つバインディングが宣言されます。この場合、ファンクションは入力を受けずにブール値を返します。

関連する問題