Как передать данные в call/cc?

Я пытаюсь реализовать функцию, которая принимает список атомов и возвращает только часть этого списка. Подчасть - это все после определенного токена. Я пытаюсь использовать call-with-current-continuation для этой цели.

Вот мой подход:

(define rest 
  (lambda (a lat)
    (call-with-current-continuation 
      (lambda (res)
        (letrec ((r (lambda (l)
                      (cond 
                        ((null? l) ())
                        ((eq? (car l) a) (res (cdr l)))
                        (else (r (cdr l)))))))
        (r lat))))))

как видите, я пытаюсь передать данные в продолжение ((eq? (car l) a) (res (cdr l))) но я всегда возвращаюсь () используя этот подход. Но если я жестко закодировал такие значения ((eq? (car l) a) (apple tea) это работает отлично.

Я действительно застрял, и мне нужна помощь.

РЕДАКТИРОВАТЬ: я нашел решение вместо (res (cdr l)) Я должен пройти (res (r (cdr l)))

Также реальная ошибка была не в том, как я звоню continuation, но с (else (r (cdr l))))))) Я должен написать как:

(else (cons (car l)
      (r (cdr l))))))))

1 ответ

Решение

Ваш код отлично работает в MIT-Scheme 9.2:

MIT/GNU Scheme running under OS X
Type `^C' (control-C) followed by `H' to obtain information about interrupts.

Copyright (C) 2014 Massachusetts Institute of Technology
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.

Image saved on Wednesday February 24, 2016 at 8:07:52 PM
  Release 9.2 || Microcode 15.3 || Runtime 15.7 || SF 4.41 || LIAR/C 4.118 || Edwin 3.116

1 ]=> (define rest
  (lambda (a lat)
    (call-with-current-continuation
      (lambda (res)
        (letrec ((r (lambda (l)
                      (cond
                        ((null? l) ())
                        ((eq? (car l) a) (res (cdr l)))
                        (else (r (cdr l)))))))
        (r lat))))))

;Value: rest

1 ]=> (rest 'c '(a b c d))

;Value 2: (d)

1 ]=> (rest 'c '(a b c d e))

;Value 3: (d e)

1 ]=> (rest 'c ())

;Value: ()

Я думаю, вы работаете с объектами, где eq? неуместная процедура сравнения

FWIW, вот более короткая реализация:

(define (rest a lat)
  (call-with-current-continuation
   (lambda (res)
     (let r ((l lat))
       (if (null? l)
           '()
           ((if (eq? (car l) a) res r) (cdr l)))))))
Другие вопросы по тегам