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

#sml #ml

#sml #ml

Вопрос:

Я пытаюсь выяснить взаимную рекурсию. У меня есть этот код:

 fun take(L)=
      if L=nil then nil
      else hd(L) :: skip(tl(L))
AND
fun skip(L)=
      if L=nil then nil
      else take(tl(L));
  

но это дает мне эти ошибки:

 stdIn:54.14-54.18 Error: unbound variable or constructor: skip
stdIn:55.1-55.4 Error: unbound variable or constructor: AND
  

Что я делаю не так?

Ответ №1:

Ваша непосредственная ошибка заключается в том, что стандартный ML чувствителен к регистру, и все его зарезервированные слова написаны в нижнем регистре; поэтому вам нужно писать and , а не AND .

Кроме того, fun вводит полное объявление, а не отдельную привязку, что означает, что вам нужно удалить лишнее fun после and .

Наконец, ваши функции в настоящее время требуют, чтобы список имел тип равенства (например, int list или string list ), что может и не нарушать условия сделки, но, учитывая, что на самом деле делают функции, на самом деле нет причин, по которым они не могут поддерживать типы, отличающиеся от равенства, такие как real list . Чтобы добиться этого, вы должны сопоставить параметр с шаблоном nil , а не проверять, равен nil ли параметр. (В более общем плане вам следует использовать сопоставление с образцом в большем количестве мест; у вас нет причин вызывать hd и tl .)

Собираем это вместе:

 fun take nil = nil
  | take (h::t) = h :: skip t
and skip nil = nil
  | skip (h::t) = take t
  

Комментарии:

1. Пытался это сделать, все, что я просто изменил ‘И’ на ‘и’ и получил эти ошибки stdIn:125.1-126.9 Error: syntax error: deleting AND FUN ID stdIn:127.2-127.6 Error: syntax error: deleting IF ID stdIn:127.11 Error: syntax error found at THEN

2. @h2oBoost: Да, извините, я только исправил ошибку в вопросе. Теперь я расширил ответ, чтобы объяснить несколько других проблем с вашим кодом (и как их исправить).

3. @h2oBoost: часть о типах равенства: если вы заметили, ваши функции имеют тип ''a list -> ''a list , в то время как функции @ruakh имеют тип 'a list -> 'a list . Совершенно необязательно требовать, чтобы элементы входного списка имели тип равенства, но еще один момент, на который следует обратить внимание, заключается в следующем: когда вы делаете xs = ys , чтобы увидеть, равны ли две вещи, это вызывает глубокий обход двух структур xs и ys ; естественно, здесь это не проблема, поскольку вы сравниваете с [] и этов конце концов, глубокий обход не так уж и глубок. Но не привыкайте сравнивать вещи, если вы можете обойтись меньшим. 🙂