Могу ли я получить альфа и логический тип из матча в Ocaml? - PullRequest
0 голосов
/ 27 марта 2019

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

Теперь поиск возвращает альфа-тип, но в моей основной функции (calcPrep) совпадение должно возвращать логическое значение, я не вижу проблемы с синтаксисом, в конце концов альфа-тип может быть логическим ...

Если я изменюсь

| '('::variable::')'::_ -> lookup (variable, dictionary)

до

| '('::variable::')'::_ -> true

совпадение работает, но, очевидно, я не получил значение переменной.

Я думаю об использовании карт в качестве словаря вместо списка пар, но для меня это сложнее ...

Вот мой код до сих пор

let rec lookup x l = 
    match l with
    | [] -> raise Not_found
    | (key, value)::rest -> 
        if key = x then 
            value
        else 
            lookup x rest

let rec calcPrep charList dictionary=
    let n = List.length charList in
    match charList with
    | '('::variable::')'::_ -> lookup (variable, dictionary)
    | '('::'!'::_ -> not (calcPrep(sublist 2 (n-1) charList) dictionary)
    | _ ->
        let pos = getPositionOperator charList 0 0 in
            let operator = (List.nth charList pos) in 
                match operator with
                | '&' -> (calcPrep (sublist 1 (pos - 1) charList) dictionary) && (calcPrep (sublist (pos + 1) (n - 2) charList) dictionary)
                | '|' -> (calcPrep (sublist 1 (pos - 1) charList) dictionary) && (calcPrep (sublist (pos + 1) (n - 2) charList) dictionary)
                | _ -> failwith ("Incorrect operator: " ^ String.make 1 (List.nth charList (pos - 1)))

1 Ответ

0 голосов
/ 27 марта 2019

Прежде всего, альфа, иначе 'a, не означает «что-нибудь», это переменная типа, которая должна рассматриваться в контексте. Например, в типе функции,

val find: ('k,'a) list -> 'k -> 'a

у нас есть две переменные типа 'k и 'a, где 'k обозначает тип ключей, а 'a обозначает тип значений. Следовательно, когда вы применяете эту функцию к какому-либо списку, например, find [1, "one"; 2, "two"], переменная 'k будет установлена ​​в int и 'a в string, а тип этого выражения будет int -> string.

Во-вторых, функция, которая проверяет, присутствует ли конкретный ключ или элемент в контейнере, обычно называется mem. Это может быть легко реализовано с помощью функции find, которая ищет элемент, например,

let mem ls k = try ignore (find ls k); false with Not_found -> true

Эта функция будет иметь тип ('k,'a) list -> 'k -> bool.

В современном OCaml предпочтительнее использовать более явный тип 'a option в качестве возвращаемого типа функции поиска, а не генерировать исключение, поскольку первый появляется в типе функции и его сложнее пропустить , Так что если у вас есть функция find, возвращающая 'a option, то реализация будет выглядеть так

let mem ls ks = match find ls k with None -> false | Some _ -> true
...