2016-11-22 4 views
2

Ich bin völlig neu in F # (begann damit heute) und relativ neu zu funktionalen Programmierung (ich habe geringe Erfahrung mit Lisp). Ich möchte eine Funktion beenden, indem Sie einen Wert zurückgeben, wenn eine bestimmte Bedingung erfüllt ist, damit der Rest der Schleife nicht ausgeführt wird. Hier ist eine C# Darstellung von dem, was ich tun möchte:Return-Wert zu Break-Funktion

bool CheckRow (int n, int i) 
{ 
    for(int j = 0; j < 9; j++) 
     if (n == sudoku[i][j]) 
      return false; 

    return true; 
} 

Ich habe versucht, die gleiche Funktion in F #, wie diese Umsetzung (Sudoku ist ein array2D):

let CheckRow (n : int) (i : int) : bool = 

    for j = 0 to 8 do 
     if (n = sudoku.[i, j]) then 
      false 

    true 

Allerdings bekomme ich folgende Fehler bei false innerhalb des if: "Dieser Ausdruck wurde erwartet, dass er type unit hat, aber hier hat bool". Was ist der richtige Weg, um innerhalb einer F # -Funktion zurückzukehren?

+3

Mögliche Duplikat von [F # Rückkehr boolean Wert in Funktion] (http://stackoverflow.com/questions/19195346/f-returning-boolean-value-in-function) –

+0

Ich würde hier annehmen, dass du das nicht auf eine idiomatische Weise machst, ich denke, du könntest den seq-Typ verwenden, um dir hier zu helfen und es funktionaler zu machen –

+1

Wenn Sie denken, dass Sie aus einer F # -Funktion vorzeitig aussteigen müssen, ist das normalerweise ein Hinweis darauf, dass Sie über das Problem falsch nachdenken. Hier möchten Sie sehen, ob in der Zeile ein Wert vorhanden ist, der eine bestimmte Bedingung erfüllt. Dafür steht die Funktion 'Array.exists'. (Oder 'List.exists' oder' Seq.exists' - siehe Bartek Kobyleckis Antwort). – rmunn

Antwort

3

Normalerweise sollten Sie die Funktion nicht früher unterbrechen müssen, sondern in einigen Fällen die Rekursion beenden, andernfalls die Funktion rekursiv aufrufen. Hier könnte die Rekursion verborgen sein, weil Sie auf Listen oder Matrizen operieren.

List.forall ist eine dieser Funktionen, die Rekursion über die Liste implementieren und das Ergebnis bei der ersten Gelegenheit zurückgibt. Man könnte schreiben Sie funktionieren auf diese Weise:

let CheckRow (expectedValue : int) (rowIndex : int) = 
    [0..8] |> List.forall (fun colIndex -> 
     sudoku.[rowIndex, colIndex] <> expectedValue) 
+2

Ich würde seq über die Liste nur wählen, weil Seq nicht auf die Sequenz mit allen Werten angewiesen ist ... –

2

Funktionen höherer Ordnung schön sind natürlich, aber irgendwann jemand eine Schleife schreiben hat (zB die Funktion höherer Ordnung zu implementieren), und das wird schließlich Sei es, also ist es schön zu wissen, wie man Loops in F # schreibt. Es besteht keine vorzeitige Rückkehr von einer for Schleife in F #, aber auch andere Arten von Schleifen es zulassen:

// While loop, imperative style 
let checkRow n i = 
    let mutable clear = true 
    let mutable j = 0 
    while clear && j < 9 do 
     clear <- n <> sudoku.[i, j] 
     j <- j + 1 
    clear 

// Tail-recursive style - more idiomatic F# 
let checkRow n i = 
    let rec loop j = 
     if j = 9 then true 
     elif sudoku.[i, j] = n then false 
     else loop (j + 1) 
    loop 0 
Verwandte Themen