2017-03-22 4 views
0
module Dfs = struct 
    let rec dfslsts g paths final = 
     let l = PrimePath.removeDuplicates (PrimePath.extendPaths g paths) 
     in 
     let f elem = 
      if (List.mem "%d" (List.flatten final) = false) then (dfslsts g ["%d"] (List.flatten l)::final) 
      else final 
     in 
     List.iter f (Graph.nodes g) 

    end 

Fehler: Dieser Ausdruck hat Typ String, sondern Ausdruck wurde vom Typ int Liste erwartetrekursive Aufruf, wenn expression - ocaml

Dieser Fehler trat auf, wenn ich dfslsts Funktion aufgerufen, die rekursiv ist, in der, wenn die Bedingung . Die Funktion dfslsts gibt eine Liste von Listen zurück. Wenn ich versuche, den komplexen Ausdruck in if-Anweisung zu

if (List.mem "%d" (List.flatten final) = false) then "%d" 
else "%d" 

dann bekomme ich Fehler zu ersetzen: Dieser Ausdruck hat Typ ‚a -> string sondern Ausdruck wurde vom Typ erwartet‘ ein -> Einheit Typ Der String ist nicht kompatibel mit dem Typ in der List.iter-Zeile.

Wie löse ich dieses Problem und darf eine rekursive Funktion innerhalb des if-Ausdrucks aufrufen.

Dies ist die Definition meiner Diagrammtyp:

module Graph = struct 

    exception NodeNotFound of int 

    type graph = { 
     nodes : int list; 
     edges : (int * int) list; 
    } 

    let makeGraph() = 
     { 
      nodes = []; 
      edges = []; 
     } 

    let rec isNodeOf g n = List.mem n g.nodes 

    let nodes g = g.nodes 

    let edges g = g.edges 

    let addNode g n = 
     let nodes = n::g.nodes and edges = g.edges in 
     { 
      nodes; 
      edges; 
     } 

    let addEdge g (n1, n2) = 
     if ((isNodeOf g n1) = false) then 
      raise (NodeNotFound n1) 
     else if ((isNodeOf g n2) = false) then 
      raise (NodeNotFound n2) 
     else 
      let nodes = g.nodes 
      and edges = (n1, n2) :: g.edges in 
      { 
       nodes; 
       edges; 
      } 

    let nextNodes g n = 
     let rec findSuccessors edges n = 
      match edges with 
       [] -> [] 
      | (n1, n2) :: t -> 
       if n1 = n then n2::findSuccessors t n 
       else findSuccessors t n 
     in 
     findSuccessors g.edges n 

    let rec lastNode path = 
     match path with 
      [] -> raise (NodeNotFound 0) 
     | n :: [] -> n 
     | _ :: t -> lastNode t 

end 

module Paths = struct 
    let extendPath g path = 
     let n   = (Graph.lastNode path) in 
     let nextNodes = Graph.nextNodes g n in 
     let rec loop path nodes = 
      match nodes with 
       []  -> [] 
      | h :: t -> (List.append path [h]) :: (loop path t) 
     in 
     loop path nextNodes 

    let rec extendPaths g paths = 
     match paths with 
      []  -> [] 
     | h :: t -> List.append (extendPath g h) (extendPaths g t) 

    (* Given a list lst, return a new list with all duplicate entries removed *) 
    let rec removeDuplicates lst = 
     match lst with 
      [] 
     | _ :: [] -> lst 
     | h :: t -> 
      let trimmed = removeDuplicates t in 
      if List.mem h trimmed then trimmed 
      else h :: trimmed 

end 

Antwort

1

Jeder Ausdruck eine rekursive Funktionsaufruf sein kann. Solche Einschränkungen gibt es nicht. Ihr Problem besteht darin, dass einige Typen nicht übereinstimmen.

Ich sehe keine Ints in diesem Code, also frage ich mich, wo der Compiler die Anforderung für eine int-Liste sieht. Es würde helfen, die Typdefinition für Ihre Graphen zu sehen.

Als Neben Kommentar, Sie mit ziemlicher Sicherheit einen Vorrang Problem mit diesem Code haben:

dfslsts g ["%d"] (List.flatten l)::final 

Der Funktionsaufruf zu dfslsts hat höhere Priorität, dass die Liste Betreiber cons ::, so wird diese analysiert als:

(dfslsts g ["%d"] (List.flatten l)) :: final 

Sie müssen wahrscheinlich so klammern:

dfslsts g ["%d"] ((List.flatten l) :: final) 
+0

(Es war eine Nebenbemerkung. Bitte zeigen Sie uns die Definition Ihres Diagrammtyps.) –

+0

Ich habe meine Frage aktualisiert, die aus einer Diagrammstruktur besteht. – Jab

+0

Hier (List.flatten l) ist eine Liste und final ist eine Liste von Listen. Ist es ein Problem mit :: dieser Notation? – Jab