Как оценить функции типа данных и true_of_all_constants? - PullRequest
0 голосов
/ 26 мая 2019

Я новичок в 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, чем заменить e?Кроме того, не могли бы вы объяснить, что здесь делает тип данных?Я не понимаю, почему нам нужно «Отрицать» или «Добавить» здесь;почему мы имеем «exp * exp» вместо «exp + exp» для «Add?»

1 Ответ

1 голос
/ 27 мая 2019

Исправление пробелов, определение типа данных и определение 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 для предиката , но это вещь вкуса.

Пытаясь оценить их, я всегда получаю ошибки

Вот несколько примеров выражений и их оценка:

- 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

Не могли бы вы объяснить, что здесь делает тип данных?

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

Например, ML для работающего программиста, гл. 4 (бесплатный PDF) имеет дело с datatype определениями.

Я не понимаю, зачем нам здесь "Negate" или "Add"

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

...