2015-05-04 3 views
0

У меня есть множество T, которые имеют элементы вида int * < Abstract> * int.Как сделать сопоставление образцов для абстрактного типа данных в OCaml?

Я хочу найти элемент этого набора, который имеет форму, скажем, 4 * < Abstract> * 5.

Когда я пытаюсь использовать

match T with 
|(4,_,5) -> Printf.printf "yes" 
|(_,_,_) -> Printf.printf "no" 

Я получаю ошибку, которая говорит: «Ошибка: Это выражение имеет тип transitionSet но выражение Ожидалось типа LOC *«а * Loc»

Как найти элемент в множестве?

+0

Вы, кажется, соответствия всего набора T, где вы хотите, чтобы соответствовать только один из его элементов. –

+0

@Sheeft Да.Есть ли другой способ, чем сделать список из T, а затем проверить это для каждого элемента в списке? –

ответ

2

Комплект абстрактно, поэтому никакой способ совпадения рисунка не имеет. В стандартном модуле библиотеки Set в OCaml, что вы можете сделать, это filter набор затем проверить его is_empty или нет:

Set.(is_empty @@ filter p t) 

где p ваш предикат.

0

Я предполагаю, что ваш комплектный модуль называется TSet, и вы используете стандартные комплекты библиотек OCaml. Я также предполагаю, что ваш набор не называется T, так как это недопустимое имя для переменных OCaml.

Если вы заботитесь только о да/нет ответа для того, существует единственное значение соответствия, вы можете сделать:

let result = 
    TSet.exists 
    (function 
    | 4, _, 5 -> true 
    | _  -> false) 
    t in 
if result then print_endline "yes" else print_endline "no" 

В общем, независимо от вашего предиката, вы можете сделать

TSet.exists p t 

Если вы хотите получить больше ответа «да/нет» и хотите иметь возможность выполнять произвольные вычисления в ветвях дела по всем совпадающим значениям в наборе, вам нужно будет использовать fold или iter с рисунком соответствия. Например, если вы хотите, чтобы добавить все первые целые числа вместе, но только тогда, когда последние целое число 5:

TSet.fold 
    (fun element accumulator -> 
    match element with 
    | x, _, 5 -> x + accumulator 
    | _  -> accumulator) 
    t 0 

Если вы хотите выполнить расчет только на первое согласующего элемента, вы можете короткий -схемная оценка с исключением. Например:

exception Found of int 

try 
    TSet.iter 
    (function 
    | x, _, 5 -> raise_notrace (Found x) 
    | _  ->()) 
    t; 
    None 
with Found x -> Some x 

Это последнее неудобно печатать снова и снова. Вы можете написать полиморфную функцию для решения проблемы поиска коротких замыканий по шаблону для себя, используя ссылку и встроенное исключение Exit. Я оставлю это как упражнение.

Это хорошая идея использовать raise_notrace, поскольку это исключение используется для нормального управления потоком. Если ваша программа за один день скомпилирована с включенными трассировками стека, raise_notrace опустит трассировку стека при выбросе исключения, что может сделать вашу программу более быстрой, если ваша функция вызывается часто.

Для справки http://caml.inria.fr/pub/docs/manual-ocaml/libref/Set.S.html

Смежные вопросы