Ocaml和返回类型(图论)

Ocaml和返回类型(图论),ocaml,graph-theory,return-type,Ocaml,Graph Theory,Return Type,我只是Ocaml中的乞丐,我想学习图论,但要用Ocaml实现。我在做一些事情时遇到了麻烦:我只想通过深度优先搜索列出一个图中连接的组件。所以,我做到了: #open "stack" ;; let non_empty pile = try push (pop pile) pile ; true with Empty -> false ;; let connected_comp g = let already_seen = make_vect (vect_length

我只是Ocaml中的乞丐,我想学习图论,但要用Ocaml实现。我在做一些事情时遇到了麻烦:我只想通过深度优先搜索列出一个图中连接的组件。所以,我做到了:

#open "stack" ;;

let non_empty pile = 
    try push (pop pile) pile ; true with Empty -> false ;;


let connected_comp g = 
    let already_seen = make_vect (vect_length g) false in
    let comp = [] in

    let dfs s lst = 
        let totreat = new () in
        already_seen.(s) <- true; push s totreat;

        let rec add_neighbour l = match l with
            | [] -> ()
            | q::r when already_seen.(q) = false -> push q totreat; already_seen.(q) <- true; add_neighbour r
            | q::r -> add_neighbour r
        in

        while non_empty totreat do
            let s = pop totreat in
            already_seen.(s) <- true;
            (* we want to add s to the list lst *) s::lst;
            add_neighbour g.(s);
        done
    in  


    let rec head_list l = match l with
        | [] -> failwith "Empty list"
        | p::q -> p
    in  
    let rec aux comp t = match t with
        | t when t = vect_length g -> comp
        | t when already_seen.(t) = true -> aux comp (t+1)
        | t -> aux ((dfs t [])::comp) (t+1) (* we want that dfs t [] return the list lst modified *)
    in aux comp 0;;
(alreadyseen是一个布尔向量,前面已定义)

我唯一的问题是,我希望函数返回list
lst
modified(在循环中),此时,它是一个单位函数

我试图将lst定义为引用,但我不知道如何返回它

我希望这更清楚,我现在还不熟悉这一切


谢谢大家!

这是您的代码的降级版本,演示了一种实现所需功能的方法

let non_empty _ = false

let dfs s lst =
  let local_lst = ref lst in

  while non_empty () do
    (*do stuff here*)
    let s = 1 in
    local_lst := s::!local_lst;
    (*do stuff here*)
  done;
  !local_lst

我首先将一个局部可变值
local_lst
初始化为作为参数给出的列表
lst
。然后在
while
循环中更新该值。最后,我返回存储在
local_lst

中的值,尝试编写代码的最低版本,该版本只包含
dfs
的定义,不依赖外部数据类型。这将使我们更容易帮助你。另外请注意,如果您想“了解OCaml”,学习编写递归函数和避免副作用是重点。请注意,代码示例是在Caml灯光下,而不是在OCaml中。它非常完美,非常感谢!是否也可以要求函数dfs的lst参数作为参考,直接修改它并在最后返回它?无论如何,非常感谢!是
lst
可以是引用,如果这样做,则不需要在末尾返回它,因为引用将被修改。然后,函数的返回类型将是
unit
,您可以重用您提供的引用作为参数。非常感谢您的所有解释!)但是使用引用并不是ocaml的方式。通常在函数式语言中,您会返回新值,而不是修改任何内容。@GoswinvonBrederlow是正确的。你应该学会不使用可变值,你会很快看到好处,因为调试变得容易多了。
let dfs s lst = 
    let totreat = new () in
    already_seen.(s) <- true; push s totreat;

    let rec add_neighbour l = match l with
        | [] -> ()
        | q::r when already_seen.(q) = false -> push q totreat; already_seen.(q) <- true; add_neighbour r
        | q::r -> add_neighbour r
    in

    while non_empty totreat do
        let s = pop totreat in
        already_seen.(s) <- true;
        (* we want to add s to the list lst *) s::lst;
        add_neighbour g.(s);
    done
in
let non_empty _ = false

let dfs s lst =
  let local_lst = ref lst in

  while non_empty () do
    (*do stuff here*)
    let s = 1 in
    local_lst := s::!local_lst;
    (*do stuff here*)
  done;
  !local_lst