2010-06-15 10 views
7

Ich versuche, eine einfache rekursive Funktion zu schreiben, die über die Liste schauen und ein Integer-Paar zurückgibt. Dies ist einfach in C/C++/Java zu schreiben, aber ich bin neu, so irgendwie schwer ocaml die Lösung, um herauszufinden, durch Konfliktocaml Muster entsprechen Frage

es geht so ..

let rec test p l = ... ;; 
val separate : (’a -> bool) -> ’a list -> int * int = <fun> 
test (fun x -> x mod 2 = 0) [-3; 5; 2; -6];; 
- : int * int = (2, 2) 

soll geben, so ist das Problem Wie kann ich rekursiv Wert auf Tupel zurückgeben.

+2

Können Sie etwas genauer angeben, was diese Funktion zurückgeben soll? Was repräsentiert das Paar von ganzen Zahlen? – goggin13

+0

so sollte es ein Paar von Ganzzahl als (x, y), die Tupel in ocaml ist , dass nur Problem, das ich konfrontiert habe Tupel Berechnung .. so ist es, wenn ein Element der Liste ist weniger als eine Zahl dann (x +1, y) else (x, y + 1), so dass der Rückgabewert (x, y) ist, wobei x die Anzahl der Elemente ist, die größer als eine Zahl ist und y kleiner als – REALFREE

Antwort

4

Sie waren bereits ein wenig von OCaml weg, aber ich denke, das ist der Trick in Bezug auf REALFREE Beschreibung in der Anmerkung tun

let rec test l = 
    match l with 
     [] -> (0,0) 
    | x::xs -> 
     if x > 0 then match (test xs) with (x,y) -> (x+1, y) 
     else match (test xs) with (x,y) -> (x, y+1);; 

Sie die Anweisungen verschachtelten Spiel verwendet werden, können Teile des Tupels zu ziehen, um ändern

EDIT: ich nicht über die Syntax Pascal Cuoq in seinem Kommentar wusste unten erwähnt, hier ist der Code wie das, es ist sauberer und etwas kürzer:

let rec test l = 
    match l with 
     [] -> (0,0) 
    | x::xs -> 
    if x > 0 then let (x,y) = test xs in (x+1, y) 
    else let (x,y) = test xs in (x, y+1);; 

Aber die akzeptierte Antwort ist noch viel besser, vor allem mit der Tail-Rekursion;).

+2

und wenn Sie ein 'match .. with ..' mit einem einzelnen Muster schreiben, können Sie stattdessen' let' verwenden: 'x, y = test xs in ...' –

5

Ein Problem hier ist, dass Sie zwei verschiedene Arten zurückgeben: ein int für eine leere Liste oder ein Tupel andernfalls. Es muss das eine oder andere sein. Ein weiteres Problem ist, dass Sie versuchen, 1 zu test hinzuzufügen, aber test ist eine Funktion, kein Wert. Sie müssen einen Test für etwas anderes aufrufen, damit ein Wert zurückgegeben wird. Aber selbst dann sollte ein Tupel zurückgegeben werden, das Sie keiner Ganzzahl hinzufügen können.

Ich kann nicht herausfinden, was Sie wollen, den Code zu tun, aber wenn Sie Ihre Frage mit dieser Info aktualisieren, kann ich mehr helfen.

Eine Vermutung, die ich habe, ist, dass Sie die positiven Zahlen in der Liste zählen möchten, in dem Fall, dass Sie es so schreiben könnte:

let rec test l = 
    match l with [] -> 0 
    | x::xs -> if x > 0 then 1 + (test xs) 
       else test xs;; 

aktualisieren: da Sie bearbeitet haben zu klären, das Problem, ändern Sie den obigen Code wie folgt:

let test l = 
    let rec test_helper l pos nonpos = 
    match l with [] -> (pos, nonpos) 
    | x::xs -> if x > 0 then test_helper xs 1+pos, nonpos 
       else test_helper xs pos 1+nonpos 
    in test_helper l 0 0;; 

Die Verwendung der Akkus helfen in diesem Fall viel. Es macht auch die Funktion tail-recursive, was immer eine gute Übung ist.

+0

ist, wie kann ich es so ändern, dass es rekursiv weiterleitet ? – REALFREE