У меня есть четыре пункта на вашей функции:
- Ваша ошибка в том, что оператор
=
предназначен для числового сравнения, а не общего равенства. Для проверки того, что список пуст, вы обычно используете функцию null?
.
- Кроме того, для оператора типа
if ... then ... else if ...
обычно используется cond
, а не if
.
- Вам не нужно
let*
здесь; unstarred let
будет делать. Фактически, я бы полностью отказался от привязок let
для этой простой функции.
- Вы действительно должны использовать обычные отступы на Лиспе и связать скобки.
Итак, ваша функция с этими изменениями:
(define (máximo lista máximo-actual)
(cond ((null? lista)
máximo-actual)
((> (car lista) máximo-actual)
(máximo (cdr lista) (car lista)))
(else
(máximo (cdr lista) máximo-actual))))
Однако более продвинутый способ написания этой функции заключается в использовании fold-left
, оператора итерации общего списка, который мы можем определить следующим образом:
(define (fold-left función valor-corriente lista)
(if (null? lista)
valor-corriente
(fold-left función
(función (car lista) valor-corriente)
(cdr lista))))
fold-left
соответствует этому распространенному типу for
-петля в императивных языках:
resultado = valor_inicial
for valor in valores:
resultado = función(valor, resultado)
return resultado
Используя fold-left
и вторую вспомогательную функцию máximo-de-dos-valores
, теперь мы имеем:
(define (máximo lista máximo-inicial)
(fold-left máximo-de-dos-valores máximo-inicial lista))
(define (máximo-de-dos-valores a b)
(if (> a b)
a
b))