2016-03-06 9 views
5

Ich versuche, eine verkettete Liste in f # mithilfe von Datensätzen zu implementieren. Ich weiß, dass ich den eingebauten Listentyp verwenden kann, aber dies dient Lernzwecken. Mein Typ ist:f # verkettete Liste mit Datensätzen implementieren

type Cell = { data : int; next : RList} 
and RList = Cell option ref 

Und ich möchte eine einfache Insert-Funktion machen, aber ich gesagt, dass f # eine boolean erwartet wurde aber ein Ausdruck des Typs Einheit gegeben. Ich frage mich, ob dies bedeutet, dass ich habe meine if/else-Anweisung falsch

let rec insert comp (item: int) (list: RList) = 
    let c = {data = item; next = ref None} 
    match !list with 
    | None -> list = cellToRList c 
    | Some {data = d; next = remaining} -> 
     if (comp(item, d)) then 
      c.next := !remaining 
      remaining := ref c (* compiler indicates error here *) 
     else insert comp item remaining 

Hinweis formatiert: comp ist jede Vergleichsfunktion unter (Punkt, d) als Eingabe und Ausgabe wahr oder falsch ab:

let compare (x, y) = x > y 

Mein Ziel ist einfach, eine neue Zelle mit Daten = Element einzufügen, wenn Vergleichsergebnisse wahr ist. Im obigen Beispiel könnte es verwendet werden, um in eine sortierte Liste einzufügen und die Sortierung beizubehalten. Die gesamte Funktion sollte Typ Einheit zurückgeben. Jeder Hinweis darauf, warum mein Dolmetscher nach einem booleschen Wert sucht, wäre willkommen!

Hinweis: Ich bin sehr neu in F #

====

mit Verbesserungen Fest mit freundlicher Genehmigung von Foggy, Mikhail, und Fyodor

type Cell = { data : int; next : (Cell option) ref} 

let rec insert compare (item: int) (list: (Cell option) ref) : unit = 
    let c = {data = item; next = ref None} 
    match !list with 
    | None -> list := Some c 
    | Some {data = d; next = remaining} -> 
     if (compare(d, item)) then 
      c.next := !remaining 
      remaining := Some c 
     else insert compare item remaining 
+0

Das beantwortet Ihre Frage nicht, aber Sie brauchen RList nicht: 'type Cell = {data: int; nächstes: Zelloption} 'https://dotnetfiddle.net/VzZwnb –

+0

Es ist eher ein Convenience Wrapper, es sei denn, Sie denken, es ist weniger bequem? – Sunny

+0

Natürlich, 'RList' redundant. –

Antwort

4

Sie eine Bool von Ihrem None zurückkehren Übereinstimmung:

| None -> list = cellToRList c 

Gleiches Zeichen ist ein Vergleichsoperator hier. Der Compiler leitet also die Funktion zurück, bool zurückzugeben, während ich denke, dass Ihre Absicht ist, unit zurückzugeben.

Wenn Sie die abgeleiteten Typen Ihrer Funktionen nicht verstehen, sollten Sie sie auf jeden Fall explizit kommentieren. In Ihrem Fall, machen Sie es

let rec insert comp (item: int) (list: RList) : unit = 

Und Sie werden das Problem sehen, dass ich oben beschrieben habe.

Sie können Typ Annotation entfernen, sobald alles kompiliert.

+0

Das macht vollkommen Sinn jetzt! Auch FYI wenn ich es explizit annotiere, wird der Compiler den Fehler in der richtigen Zeile finden. – Sunny