Печать int -> int list в ocaml - PullRequest
0 голосов
/ 10 января 2020

Функция '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 - это сам график, и значением являются (node1, weight, node2). Когда я передаю в функцию succ_di_nodo значение, например (succ_di_nodo g1 4), оно возвращает правильно: int list = [3; 6].

Вопрос в том, когда я вызываю функцию (succ_di_nodo g1), не давая конкретный c узел возвращает тип int -> int list; так что это не пустой список, и я хочу увидеть точное возвращаемое значение этого вызова функции. Как напечатать список типов int -> int в Ocaml?

1 Ответ

0 голосов
/ 10 января 2020

Когда вы вызываете succ_di_nodo только с одним аргументом, он возвращает функцию, которая принимает второй аргумент и возвращает список преемников. Это называется частичное применение .

Тип int -> int list обозначает функцию, которая принимает один аргумент типа int и возвращает значение типа int list. Вы не можете напечатать значение функции (принтер по умолчанию просто напечатает <fun>). Чтобы напечатать функцию, вам нужно будет перечислить все значения во входной области, которая обычно бесконечна (или близка к ней). В целях тестирования вы, конечно, можете применить свою функцию к набору входных значений, чтобы увидеть, что она выводит, например,

List.init 10 (succ_di_nodo g1);;

будет применять (succ_di_nodo g1) к 0, 1 и т. д. до 9 и возвращают результат в виде списка, т. е. результат будет

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

Вы также можете отслеживать свою функцию на верхнем уровне (т. е. когда вы выполняете свою функцию в интерпретаторе), используя директиву #trace. Он покажет аргументы, которые go в функцию и значения, которые go выход. Ради эксперимента попробуйте это на верхнем уровне:

#trace succ_di_nodo;;

(вам нужно ввести ведущий #, это часть имени директивы). Когда вы примените succ_di_nodo к двум аргументам, вы заметите, что функция сначала возвращает новую функцию с кодовым названием succ_di_nodo*, которая является результатом применения первого аргумента, и, наконец, второй аргумент передается возвращенная функция succ_di_nodo*. Этот процесс называется curry , который является важной концепцией в функциональном программировании.

# #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.

...