2017-03-22 28 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 

错误:此表达式类型的字符串,但预计int类型列表中的表达递归调用中,如果表达 - ocaml的

当我打电话dfslsts功能,这是递归的这个错误发生,如果条件内。 函数dfslsts返回列表的列表。 如果我试图取代if语句

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

那么复杂的表情,我得到 错误:此表达式的类型为“A - >字符串 但预计类型的表达式” a - >单元 类型字符串与List.iter行中的类型单元 不兼容。

如何解决这个问题,我们可以在if表达式中调用递归函数。

这是我的图形类型的定义:

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 

回答

1

任何表达式可以是递归函数调用。没有这样的限制。你的问题是有些类型不匹配。

我在代码中看不到任何整数,所以我想知道编译器在哪里看到int列表的需求。这将有助于查看图形的类型定义。

作为一个边评论,你几乎可以肯定有一个优先问题,此代码:

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

的函数调用dfslsts具有更高的优先级,该列表负面因素运营商::,所以这被分析为:

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

你可能需要加上括号是这样的:

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

(这是一条评论。请向我们展示您的图表类型的定义。) –

+0

我更新了由图结构组成的问题。 – Jab

+0

这里(List.flatten l)是一个列表,最后是列表的列表。这是使用::这种表示法的问题吗? – Jab