在 ocaml 中打印 int -> int 列表

Printing int -> int list in ocaml

函数'succ_di_nodo'打印给定图中给定节点的后继节点:

type peso = int;;
type 'a grafo = Gr of (int * peso * int) list;;
let g1 =  Gr [(1,3,2);(1,9,5);(2,2,3);(5,4,6);(3,1,6);(3,7,4);(6,2,7);(4,4,6)];;

let rec succ_di_nodo (Gr grafo) nodo =
    let rec f_ausiliaria = function
        [] -> []
        | (x,y,z)::coda -> 
            if x = nodo then z::f_ausiliaria coda
            else if z = nodo then x::f_ausiliaria coda
            else f_ausiliaria coda in f_ausiliaria grafo;;

g1是Graph本身,值为(node1,weight,node2)。 当我将值传递给函数 succ_di_nodo 例如 (succ_di_nodo g1 4) 它 returns 正确: int list = [3;6].

问题是,当我调用函数 (succ_di_nodo g1) 时没有给出特定节点 return 类型 int -> int 列表;所以它不是一个空列表,我想查看此函数调用的确切 return 值。我如何在 Ocaml 中打印类型 int -> int 列表?

当您仅使用一个参数调用 succ_di_nodo 时,它 return 是一个接受第二个参数的函数,并且 return 是后继列表。这叫做partial application

int -> int list 类型表示一个函数接受一个 int 类型的参数和 return 一个 int list 类型的值。您不能打印函数值(默认打印机只会打印 <fun>)。为了打印一个函数,您需要枚举输入域中的所有值,这通常是无限的(或接近无限的)。出于测试目的,您当然可以将函数应用于一组输入值,以查看其输出结果,例如

List.init 10 (succ_di_nodo g1);;

会将 (succ_di_nodo g1) 应用到 01,依此类推,直至 9 和 return 列表中的结果,即输出将是

[[]; [2; 5]; [1; 3]; [2; 6; 4]; [3; 6]; [1; 6]; [5; 3; 7; 4]; [6]; []; []]

您还可以使用 #trace 指令在顶层跟踪您的函数(即,当您 运行 解释器中的函数时)。它将显示进入函数的参数和输出的值。为了实验的缘故,在顶层试试这个:

#trace succ_di_nodo;;

(您需要键入前导 # 它是指令名称的一部分)。当您将 succ_di_nodo 应用于两个参数时,您会注意到该函数首先 return 是一个新函数,代号为 succ_di_nodo*,这是应用第一个参数的结果,并且,最后,第二个参数被传递给 returned succ_di_nodo* 函数。这个过程称为currying,这是函数式编程中的一个基本概念。

# #trace succ_di_nodo;;
succ_di_nodo is now traced.
# succ_di_nodo g1 0;;
succ_di_nodo <--
  Gr
   [(1, 3, 2); (1, 9, 5); (2, 2, 3); (5, 4, 6); (3, 1, 6); (3, 7, 4);
    (6, 2, 7); (4, 4, 6)]
succ_di_nodo --> <fun>
succ_di_nodo* <-- 0
succ_di_nodo* --> []
- : int list = []
# 

完成后,您可以使用 #untrace 指令取消跟踪函数。