Function if表达式中的递归调用-ocaml
错误:此表达式的类型为string,但表达式的类型应为int list 在if条件内调用dfslsts函数时发生此错误,该函数是递归的。 函数dfslsts返回列表列表。 如果我尝试将If语句中的复杂表达式替换为Function if表达式中的递归调用-ocaml,function,loops,recursion,ocaml,Function,Loops,Recursion,Ocaml,错误:此表达式的类型为string,但表达式的类型应为int list 在if条件内调用dfslsts函数时发生此错误,该函数是递归的。 函数dfslsts返回列表列表。 如果我尝试将If语句中的复杂表达式替换为 module Dfs = struct let rec dfslsts g paths final = let l = PrimePath.removeDuplicates (PrimePath.extendPaths g paths)
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
然后我得到
错误:此表达式具有类型“a->string”
但表达式应为“a->unit”类型
类型字符串与类型单位不兼容
在List.iter线上
我如何解决这个问题?我们是否可以在if表达式中调用递归函数
这是我的图形类型的定义:
if (List.mem "%d" (List.flatten final) = false) then "%d"
else "%d"
任何表达式都可以是递归函数调用。没有这样的限制。你的问题是有些类型不匹配 我在这段代码中没有看到任何int,所以我想知道编译器在哪里看到int列表的需求。查看图形的类型定义会有所帮助 作为旁注,您几乎肯定会遇到此代码的优先级问题:
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
对DFSLTS的函数调用的优先级高于list cons运算符:,因此将其解析为:
dfslsts g ["%d"] (List.flatten l)::final
您可能需要这样插入括号:
(dfslsts g ["%d"] (List.flatten l)) :: final
这是附带的评论。请告诉我们你的图表类型的定义。我已经更新了我的问题,它由图表结构组成。这里List.flatte l是一个列表,final是列表的列表。使用::这个符号有问题吗
dfslsts g ["%d"] ((List.flatten l) :: final)