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 list
当我在if条件中调用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
答案 0 :(得分:1)
任何表达式都可以是递归函数调用。没有这样的限制。你的问题是某些类型不匹配。
我在这段代码中没有看到任何内容,所以我想知道编译器在哪里看到int列表的要求。查看图表的类型定义会有所帮助。
作为旁注,您几乎肯定会对此代码存在优先级问题:
dfslsts g ["%d"] (List.flatten l)::final
对dfslsts
的函数调用优先于list cons运算符::
,因此将其解析为:
(dfslsts g ["%d"] (List.flatten l)) :: final
您可能需要像这样括号:
dfslsts g ["%d"] ((List.flatten l) :: final)