2016-09-21 3 views
0

Я не знаком с SML, но я написал следующую программу:конструктор данных, используемый без аргумента в шаблоне?

datatype 'a bin_tree = Leaf of 'a 
| Node of 'a bin_tree * 'a bin_tree 

fun height Leaf (x) = 0 
| height Node (l1,l2) = 1 + Int.max(l1,l2) 

fun is_balanced Leaf (x) = true 
| is_balanced Node (l1,l2) = 
    if(abs(height(l1) - height(l2))<2) 
     then (is_balanced(l1); is_balanced(l2)) 
    else false 

val prod_tree = fold_tree 
    op* (fn x => x) 

fun fold_tree e f Leaf (x) = f(x) 
| fold_tree e f Node (l1, l2) = (e(fold_tree e f(l1)), e(fold_tree e f(l2))) 

Однако, когда компилируется use "lab2.sml"; я получаю следующее сообщение об ошибке:

lab2.sml:4.12-4.16 Error: data constructor Leaf used without argument in pattern 
lab2.sml:5.10-5.14 Error: data constructor Node used without argument in pattern 
lab2.sml:7.17-7.21 Error: data constructor Leaf used without argument in pattern 
lab2.sml:8.15-8.19 Error: data constructor Node used without argument in pattern 
lab2.sml:9.10-9.33 Error: operator and operand don't agree [overload conflict] 

Я сделал но, возможно, я просто что-то упустил. Любая помощь будет принята с благодарностью. Благодаря!

ответ

3

Существует ряд проблем. Поскольку это, кажется, домашнее задание, я укажу несколько вещей, но позвольте вам детализировать детали:

1) В SML приложение-приложение имеет наивысший возможный приоритет. Таким образом, линия

fun height Leaf (x) = 0 

разбирает, как

fun (height Leaf) x = 0 

, а не предполагаемого

fun height (Leaf x) = 0 

Обратите внимание, что (height Leaf) имеет функцию height, приложенную к конструктору Leaf, где Leaf не имеет аргумента - следовательно, критическое сообщение об ошибке data constructor Leaf used without argument in pattern. Вы повторяете по существу ту же ошибку в других местах вашего кода. Решение во всех случаях заключается в том, чтобы помещать скобки вокруг выражения конструктора; например используйте (Leaf x), а не Leaf (x).

2) Int.max(l1,l2) не имеет смысла с l1 и l2 - это деревья, а не целые числа. Вероятно, вы хотели взять высоту этих деревьев.

3) ; не является булевым оператором. andalso есть.

4) Вы пытаетесь использовать fold_tree, прежде чем определили его. Определите это первым.

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

+0

Поскольку оператор ';' имеет тип ''a *' b -> 'b', он определенно определен для булевых. :-P –

+0

@SimonShine Хорошая точка. Я предполагаю, что это будет булевский оператор проектирования. Я должен был сказать, что это не полезный логический оператор (хотя я уверен, что вы можете придумать умный случай использования). –

+0

Сортировка, да. При тестировании побочных эффектов: «val test = (expected_to_fail (...); false) handle ExpectedExn ... => true | _ => false' –