2016-10-13 18 views
1

私は関数型プログラミングには新しく、ループ内でこれらのステートメントを実行しようとしていますが、タブがf#で許可されないというエラーが表示されます。助けてください。私が間違っているなら、これはもっと多くの誤りを含んでいるかもしれません。すべてのF#:ループ内で複数のステートメントを実行するには

open System 
let sum:int32=0,sum2:int32=0,sum3:int32=0; 
let function1(num:int32) = 
for i = 1 to num do 
    sum = sum + i 
    sum2 = sum2 + (i+1) 
    sum3 = sum3 + (i+2) 
printfn "%i %i %i" sum sum2 sum3 

function(11) 
+0

[this](https://www.emacswiki.org/emacs/TabsSpacesBoth)には誰も驚いていません。また、高階関数などのリストを返すバージョンを追加しました。 – s952163

答えて

2

まずあなたは基本的なF# syntaxにいくつか紹介をお読みください。これはあまり慣用的ではありませんF#、関数型プログラミングの1つの目的は可変変数を避けることです。

open System 
let mutable sum = 0 
let mutable sum2 = 0 
let mutable sum3 = 0 
let function1 num = 
    for i = 1 to num do 
    sum <- sum + i 
    sum2 <- sum2 + (i+1) 
    sum3 <- sum3 + (i+2) 
    printfn "%i %i %i" sum sum2 sum3 

function1 11 

この機能を数回実行して、これが良い考えではないことを確認してください。ヒント、あなたは少なくとも関数スコープの中で可変変数を定義すべきです。タブ、使用スペースを使用しないでください:

let sumFunc2 num = 
    [for i in 1..num -> 
    List.init i (fun x -> x+1)] 
    |> List.map List.sum 
    |> List.mapi (fun i x -> [x;x+i+1;x+2+2*i]) 

sumFunc2 4 
+1

最後にsumFunc2の "List.last"がありませんか? –

+0

@HenrikHansenそれは良い質問であり、実際にOPの意図に依存しています。彼のQでは、printfnはforループの外にありますが、それはうまく動作しません。その理由は、OPが合計変数を定義してから関数を定義し、その関数を実行するためです。実際には、それは何も印刷されません(最初は0,0,0)。だから私はforループの中でprintfnを引っ張ったのです。これでprintfnはまだ関数の中にあるが、forループの外側にある可能性がある。あなたはList.lastにタグを付けることができますが、必要な場合はできることがありますが、それをする必要はありません。 – s952163

+1

OK、良い引数:-) –

1

は、私は、エラーメッセージが自身のために語って言うだろう:

編集 そして、ここでは、リスト操作関数の様々なバージョンです。

それ以外の場合(そしてあなたがletと同じようにバインドを区切るためにカンマを使用できないという事実)、コードは構文的に有効です。つまり、ループ内で複数のことを行い、あなたがしたように、レベル。

意味的にはあなたが望むことはしません。 =はF#の等価演算子であり、代入ではありません。プラス変数はデフォルトでは不変です。必要な処理を行うには、変数を可変として宣言し、代入演算子<-を使用する必要があります。

しかし、これの結果は関数型プログラミングではなく、F#で行われる命令型プログラミングだけになります。機能的な方法は、高階関数および/または再帰を使用し、可変変数をまったく使用しないことです。

+1

これは例えば構文上有効ではないと確信しています: 'let sum:int32 = 0、sum2:int32 = 0、sum3:int32 = 0; ' – s952163

+2

@ s952163そうです、私はそれを逃しました。私はループだけを見ていた。それは唯一の事だと思われる。 – sepp2k

1

他の人がすでに述べたように、可変変数は機能プログラミング/ F#で(ほとんど)悪いです。代わりに、データのシーケンスを処理することだけです。

多くの場合、List.foldは、C++やC#のような他の言語での繰り返しを使用する場所で非常に便利です。あなたの質問のためのList.foldと

簡単な解決策は次のようになります。最後(0, 0, 0)上記tripleSumで

open System 

let tripleSum n = 
    [1..n] |> List.fold (fun (s1, s2, s3) x -> (s1 + x, s2 + 1 + x, s3 + 2 + x)) (0, 0, 0) 

[<EntryPoint>] 
let main argv = 
    let sum1, sum2, sum3 = tripleSum 3 
    printfn "%d, %d, %d" sum1 sum2 sum3 

    Console.ReadLine() |> ignore 
    0 // return an integer exit code 

は3個の合計のための初期シード値である、と彼らは呼ばれる折り機能(fun (s1, s2, s3) ->...によってまとめリスト内の各要素について[1..n]

関連する問題