Я новичок в sml и посещаю курсы по языку программирования на Coursera. Есть тип данных и функция, которую я не знаю, как оценить:
datatype exp = constant of int
| Negate of exp
|Add of exp * exp
|Multiply of exp * exp
fun true_of_all_constants(f,e) =
case e of
constant i => f i
| Negate e1 => true_of_all_constants(f,e1)
| Add(e1,e2) => true_of_all_constants(f,e1)
andalso true_of_all_constants(f,e2)
| Multiply(e1,e2) => true_of_all_constants(f,e1)
andalso true_of_all_constants(f,e2)
Пытаясь их оценить, я всегда получаю ошибки:
true_of_all_constants [3,4,5];
true_of_all_constants 4;
true_of_all_constants (is_even 4, 5);
где is_even — небольшая вспомогательная функция:
fun is_even v =
(v mod 2 = 0)
Что нужно заменить, чтобы проверить true_of_all_constants? Кроме того, не могли бы вы объяснить, что здесь делает тип данных? Я не понимаю, зачем здесь нужно «Отменить» или «Добавить»; почему у нас есть "exp*exp", а не "exp+exp" для "Добавить?"
«не могли бы вы объяснить, что здесь делает тип данных?» — вы спрашиваете, что здесь означает ключевое слово datatype
, или вы спрашиваете, каково значение и назначение этого конкретного типа данных exp
?
@Bergi Обновил мою операцию. Пожалуйста, взгляните. Спасибо!
Вызов должен выглядеть как true_of_all_constants(is_even, Constant 4)
или true_of_all_constants(is_even, Add(Negate(Constant 2), Multiply(Constant 3, Constant 4)))
@Bergi Что делает «Добавить» в «Добавить (Отменить (Константа 2))?» Будет ли это (-2)+(-2)=-4?
Он создает экземпляр вашего типа данных. Он ничего не вычисляет, он создает абстрактное представление такого математического выражения.
Исправление пробелов, определение типа данных и определение true_of_all_constants (p, e)
становятся:
datatype exp =
Constant of int
| Negate of exp
| Add of exp * exp
| Multiply of exp * exp
fun true_of_all_constants (p, e) =
let fun aux (Constant i) = p i
| aux (Negate e1) = aux e1
| aux (Add (e1, e2)) = aux e1 andalso aux e2
| aux (Multiply (e1, e2)) = aux e1 andalso aux e2
in aux e end
Здесь constant
был переименован в Constant
: оба будут работать, но имена конструкторов с заглавной буквой визуально отличают их от других идентификаторов. И я использовал внутреннюю функцию aux
, чтобы немного сократить рекурсивные выражения. Вместо f
я назвал его p
для предикат, но это дело вкуса.
Trying to evaluate them, I always get errors
Вот несколько примеров выражений и их вычисление:
- val two_plus_two = Add (Constant 2, Constant 2);
- true_of_all_constants (fn i => i = 2, two_plus_two);
> val it = true : bool
- val two_times_neg_two = Multiply (Constant 2, Constant ~2);
- true_of_all_constants (fn i => i > 0, two_times_neg_two);
> val it = false : bool
- val two_four_six = Add (Constant 2, Add (Constant 4, Constant 6));
- fun is_even x = x mod 2 = 0;
- true_of_all_constants (is_even, two_four_six);
> val it = true : bool
could you explain what does datatype do here?
Я думаю, вам следует обратиться к книге или учебнику здесь.
Например, ML для работающего программиста, гл. 4 (бесплатный PDF) имеет дело с определениями datatype
.
I don't understand why we need "Negate" or "Add" here
Я тоже не знаю. Проблема, которую вам дали в курсе, полностью гипотетическая.
"Пытаясь их оценить, я всегда получаю ошибки" - покажите нам код, который вы пытаетесь оценить