2015-12-24 10 views
1

Я пишу небольшой скрипт с некоторыми утилитами комбинаторики. Когда мне нужен числовой литерал, такой как 0 или 1 в другом типе, я использую _0 и _1, но это решение является менее идеальным. Можно ли использовать Camlp4 для реинтерпретации числовых литералов в заданном контексте или добавления нового типа числового литерала с выделенным суффиксом?OCaml перегружает числовой литерал с помощью Camlp4

open Num 
let zero = num_of_int 0 
let one = num_of_int 1 
let _0 = zero 
let _1 = one 

(* some useful infix operators *) 
let (+) = (+/) 
let (-) = (-/) 
let (*) = (*/) 
let (<) = (</) 
let (>) = (>/) 
let (=) = (=/) 
let (/) numer denom = 
    if mod_num numer denom = _0 
    then div_num numer denom 
    else invalid_arg "division is not a total function" 

(* factorial, naive *) 
let rec fact n = 
    if n < _0 
    then invalid_arg "negative factorial" 
    else if n = _0 
    then _1 
    else 
     n * fact (n - _1) 

(* naive algorithm *) 
let choose n k = (fact n/fact k)/fact (n - k) 
+0

С открытым номером вы можете написать 'let i = Int 4', который не очень громоздкий. И трюк с определяющими числами нуль, один и два можно увидеть довольно часто в коде. –

ответ

1

Одним словом, нет. Camlp4 является препроцессором нетипизированного дерева разбора. Он не может делать такую ​​чувствительную вещь.

Если вы захотите (и я уверен, что вы этого не сделаете), вы можете запустить проверку типов против нетипизированных деревьев синтаксического анализа в Camlp4 и вывести типы ваших специальных цифр, а затем заменить их на соответствующие значения. Теоретически это возможно, но никто никогда не пробовал этого, поскольку дерево разбора P4 полностью отличается от дерева OCaml.

Препроцессор PPX, предназначенный для замены Campl4, имеет определенную надежду, поскольку он обрабатывает то же самое нетипизированное дерево разбора, что и OCaml, и поэтому легко применять OCaml type checker. TyPPX (https://bitbucket.org/camlspotter/typpx) является такой основой для предоставления API-интерфейсов для предварительной обработки по типу.

1

Вы можете взглянуть на delimited overloading - он требует, чтобы квалифицировать ваши постоянные окружив выражение e с M.(e) где M это имя вашего модуля (можно определить псевдонимы).

+0

Я читал о разграниченной перегрузке раньше, но я несколько смущен о том, как использовать его в проекте. Нужно ли включать расширение как флаг компилятора? Есть ли способ включить директиву в ваш источник, чтобы компиляция не срабатывала предсказуемым образом, если расширение отсутствует, а верхние уровни, такие как 'utop', будут загружать его автоматически? –

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

  • Нет связанных вопросов^_^