Как использовать несколько операторов внутри цикла do в схеме?

#scheme

#схема

Вопрос:

Проблема
Подсчитайте количество вхождений в список, они должны быть смежными. Пример: (a a b b c c a e) , возвращает ( (a 2) (b 2) (c 2) (a 1) (e 1) ) .

Я пытался,

 (define (loop lst) 
  (let ((i 1) (j 0))
    (do ()
      [(> j (- (length lst) 2))]
      (if (eq? (car lst) (cadr lst))
          (set! i (  i 1))
          (display i)
      )
      (
         (set! lst (cdr lst))
         (set! j (  j 1))
      )
    )
  )
)
  

При запуске DrScheme пожаловался

 procedure application: expected procedure, given: #<void>; arguments were: #<void>
  

Как я могу использовать несколько операторов внутри if или do цикла, подобного этому?

Спасибо,

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

1. -1 Мои глаза! Очки ничего не делают!

2. @Chris Jester-Young: Я не понимаю?

3. Что вы пытаетесь сделать? Это не похоже ни на один код, который захотел бы написать здравомыслящий программист.

4. @Chris Jester-Young: Прости меня! Сейчас я очень стараюсь изучить Scheme. Я был так одержим традиционной структурой императивного языка. Мне было крайне неудобно использовать круглые скобки в качестве блока кода. Честно говоря, я почти сдался!

5. Верно, и именно поэтому я только что отправил вам ответ, основанный на fold . Как только вы освоитесь с fold , map и т.д., вам больше не захочется использовать циклы в императивном стиле. 🙂 (Кстати, я только что отозвал свой отзыв. Спасибо за объяснение вашей задачи.)

Ответ №1:

О, вы хотите вычислить длину пробега! Угадай что! Еще одна проблема для fold ! 😛

 (define (run-lengths lst)
  (fold-right (lambda (elem result)
                (if (and (pair? result)
                         (equal? elem (caar result)))
                    (cons (cons elem (  (cdar result) 1)) (cdr result))
                    (cons (cons elem 1) result)))
              '() lst))
  

(Моя версия возвращает длины выполнения в виде пар с точками, а не списков длины 2.) Поскольку вы используете Racket, вы можете использовать foldr вместо fold-right ; таким образом, вам не нужно будет загружать SRFI 1.

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

1. @Крис Джестер-Янг: Теперь ты режешь мне глаза. Спасибо!

2. @Чан: Хахаха. Сделайте все возможное, чтобы изучить, как работает моя функция, прочитав о том, как foldr это работает. Это просветит вас! 🙂

3. @Крис Джестер-Янг: Ну, я знаком со значением слова «сгиб». Я читал из wiki, это похоже на std::accumulate в C . Тем не менее, () это было супер раздражающе : (!

4. @Chan: Это в точности как std::accumulate . 🙂 Однажды вы привыкнете смотреть на скобки (или, скорее, не смотреть на них). 🙂

5. @Chan: Обратите внимание также на разницу в структуре кода. Разработчики Lisp не помещают «висячие» скобки в строку так же, как программисты на языке C * обычно помещают фигурные скобки в строку. Это на самом деле увеличивает читаемость вашего кода. Для получения дополнительной информации ознакомьтесь с этим руководством по стилю lisp: mumble.net /~campbell/scheme/style.txt