#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
; естественно, здесь это не проблема, поскольку вы сравниваете с[]
и этов конце концов, глубокий обход не так уж и глубок. Но не привыкайте сравнивать вещи, если вы можете обойтись меньшим. 🙂