стандартный мл добавить элементы в пользовательский тип данных

Я хочу создать функцию для нового типа данных в Standard ML, тип данных называется intnest и определяется следующим образом:

datatype intnest = 
  INT of int
| LIST of intnest list;

и я хочу сделать функцию, которая добавляет все целые числа в intlist, я попробовал следующий код:

fun addup (INT n) = n
  | addup (LIST x::xs) = x + addup(xs);

Что я делаю неправильно?

РЕДАКТИРОВАТЬ:

Я также пробовал следующее:

fun addup (INT n) = n
  | addup (LIST x::xs) = addup(x) + addup(xs);

так что x имеет тип INT, поэтому первая опция возвращает значение int, а addup(xs) является рекурсивным вызовом для возврата той же второй опции.

Также пробовал следующее:

fun addup (INT n) = n
  | addup (LIST []) = 0
  | addup (LIST x::xs) = addup(x) + addup(LIST xs);

но я получаю следующую ошибку:

stdIn:146.4-151.50 Error: parameter or result constraints of clauses don't agree [tycon mismatch]
  this clause:      intnest list -> 'Z
  previous clauses:      intnest -> 'Z
  in declaration:
    addup =
      (fn INT n => n
        | LIST nil => 0
        | :: (<pat>,<pat>) => addup <exp> + addup <exp>)
stdIn:151.25-151.50 Error: operator and operand don't agree [tycon mismatch]
  operator domain: intnest
  operand:         intnest list
  in expression:
    addup x

person hakuna matata    schedule 28.03.2012    source источник


Ответы (1)


Во-первых, в случае LIST есть синтаксическая ошибка; избавиться от of. Вы хотите, чтобы дело выглядело как addup (LIST(x::xs)) = ....

Более того, в addup есть концептуальные проблемы. Желаемый тип addup выглядит как intnest -> int. Таким образом, необходимо убедиться, что addup всегда применяется к intnest значениям и возвращает int значений.

Теперь рассмотрим тип элементов списка x::xs. Вы определили его как LIST of intnest list, поэтому x — это intnest. Но в addup вы обрабатываете x как целое число.

В том же духе, xs — это intnest list, но это не intnest, как вы относитесь к нему как к addup(xs). Ваша исправленная версия решает проблему с x, но не с xs. Вам нужно сделать intnest из xs, используя LIST, а это значит, что вам нужно будет использовать addup(LIST xs).

Наконец, вы пропустили дело. Что происходит, когда у вас есть LIST []?

Третья версия не работает, потому что вам не хватает скобок. Компилятор сообщает вам, что вы используете intnest list в качестве одного из случаев (случай ::). То есть он видит LIST x::xs как (LIST x) :: xs.

person Michael J. Barber    schedule 28.03.2012
comment
Я не совсем вас понял, разве xs не является списком intnest? - person hakuna matata; 28.03.2012
comment
@aizen92 Да, именно так. Но тип, который вам нужен для addup, это intnest. Ваш случай LIST реализован с использованием intnest list, но не intnest list. Может помочь сравнение типов xs и LIST xs. - person Michael J. Barber; 28.03.2012
comment
Проблема заключалась в скобках между x::xs, но я не совсем понимаю, почему это так, разве x::xs не считается одним проектом, который является списком? - person hakuna matata; 28.03.2012
comment
@aizen92 :: — это конструктор типов для списков, аналогичный LIST и INT в вашем типе данных intnest. SML использует это для деконструкции списка при сопоставлении с образцом. Вот почему этот случай для :: появляется в сообщении об ошибке. - person Michael J. Barber; 28.03.2012