2016-10-13 2 views
1

Ich bin neu in der funktionalen Programmierung und ich habe versucht, diese Anweisungen in der Schleife auszuführen, aber es gibt mir eine Fehlermeldung, Tabulatoren sind in F # nicht erlaubt. bitte hilfe. Dies könnte mehr Fehler enthalten. Bitte korrigieren Sie mich, wenn ich falsch liege.F #: Wie man mehrere Anweisungen in einer Schleife ausführt

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

Ich bin überrascht, niemand verknüpft [this] (https://www.emacswiki.org/emacs/TabsSpacesBoth). Ich fügte auch eine Version mit Funktionen höherer Ordnung, etc. hinzu, die eine Liste zurückführt. – s952163

Antwort

2

Zunächst sollten Sie einige Einführung zu grundlegenden F# syntax lesen. Dies ist nicht sehr idiomatisch F #, ein Ziel der funktionalen Programmierung ist es, veränderliche Variablen zu vermeiden.

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 

Sie sollten diese Funktion ein paar Mal ausführen und sehen, warum dies keine gute Idee ist. Tipp, Sie sollten zumindest die veränderbaren Variablen innerhalb des Funktionsumfangs definieren.

bearbeiten Und hier ist eine Version mit einer Vielzahl von Funktionen Liste Manipulation:

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

sollst du am Ende in sumFunc2 kein "|> List.last" haben? –

+0

@HenrikHansen Das ist eine gute Frage und hängt wirklich von der Absicht des OP ab. In seinem Q befindet sich der Printfn außerhalb der for-Schleife, aber das funktioniert nicht so. Der Grund ist, dass das OP die Summenvariablen definiert, dann eine Funktion definiert und dann die Funktion ausführt. In der Tat wird es nichts drucken (gut 0,0,0 zum ersten Mal). Deshalb habe ich den Printfn innerhalb der for-Schleife gezogen. Nun ist es möglich, dass sich der Printfn immer noch innerhalb der Funktion, aber außerhalb der for-Schleife befindet. Dann können Sie sicherlich auf einer List.last markieren, aber der Vorteil ist, dass Sie können, wenn Sie wollen, aber Sie müssen das nicht tun. – s952163

+1

OK, gute Argumente :-) –

1

ich die Fehlermeldung spricht für sich selbst sagen würde: Sie, Leerzeichen Verwendung nicht Registerkarten verwenden.

Anders als das (und die Tatsache, dass Sie Kommas nicht verwenden können, um Bindings zu trennen, lassen Sie wie Sie), Ihr Code sieht syntaktisch gültig, das heißt, mehrere Dinge in einer Schleife zu tun, Sie einrücken sie gleichzeitig Niveau, wie Sie es taten.

Semantisch wird es aber nicht tun, was Sie wollen. = ist der Gleichheitsoperator in F #, nicht Zuweisung. Plus-Variablen sind standardmäßig unveränderbar. Um das zu tun, was Sie wollen, müssen Sie die Variablen als veränderbar deklarieren und den Zuweisungsoperator <- verwenden.

Das sagte jedoch, das Ergebnis davon wird keine funktionale Programmierung sein, nur imperative Programmierung in F # getan. Der funktionale Weg wäre die Verwendung von Funktionen höherer Ordnung und/oder Rekursion und keine veränderbaren Variablen.

+1

das ist zum Beispiel ich bin sicher nicht syntaktisch gültig: 'let Summe: int32 = 0, sum2: int32 = 0, sum3: int32 = 0; ' – s952163

+2

@ s952163 Sie haben Recht, ich habe das vermisst. Ich schaute nur auf die Schleife. Das scheint aber das einzige zu sein. – sepp2k

1

Wie andere bereits festgestellt haben, sind veränderbare Variablen in der funktionalen Programmierung/F # (fast) fast schlecht. Stattdessen geht es um die Verarbeitung von Datenfolgen.

Ich finde oft List.fold sehr nützlich an Orten, wo ich eine Iteration in anderen Sprachen wie C++ oder C# verwendet hätte.

könnte eine einfache Lösung mit List.fold für Ihre Frage:

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 

In tripleSum oberhalb den letzten (0, 0, 0) sind die anfänglichen Startwerte für die drei Summen, und sie fasst (fun (s1, s2, s3) ->... durch die Faltung Funktion aufgerufen für jedes Element in der Liste [1..n]

Verwandte Themen