Изучаю язык по MIT'овской книжке (ссылка здесь где-то проскакивала).
Второй день ломаю голову над задачей (видно, трудно перестроиться на их образ мышления)
Там в одной из задач (3.50) предложено написать обобщённую функцию stream-map, заполнив недостающие фрагменты:
(define (stream-map proc . argstreams)
(if (<...> (car argstreams))
the-empty-stream
(<...>
(apply proc (map <...> argstreams))
(apply stream-map
(cons proc (map <...> argstreams))))))
Честно говоря, я в ауте. Подскажите, как это сделать?
Вообще, мне кажется, всё упирается в функцию apply.
Опять-таки не понимаю, как она должна быть реализована... По идее она должна применять какую-либо операцию к списку.
Т.е. для бинарной операции что-то типа:
(define (apply proc args)
(if (= (length args) 1)
(car args)
(proc (car args) (apply proc (cdr args)))))
Тогда stream-map я бы сделал несколько иначе:
(define (stream-map proc . argstreams)
(if (stream-null? (car argstreams))
the-empty-stream
(cons-stream
(apply proc (map stream-car argstreams))
(stream-map proc (map stream-cdr argstreams)))))
где map задана в виде:
(define (map proc items)
(if (null? items)
'()
(cons (proc (car items))
(map proc (cdr items)))))
Но как быть, например, если операция, например, триарная? Или в общем случае n-арная?
Объясните, плиз.
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Здравствуйте, frogkiller, Вы писали:
F>Вообще, мне кажется, всё упирается в функцию apply.
F>Опять-таки не понимаю, как она должна быть реализована... По идее она должна применять какую-либо операцию к списку.
apply применяет процедуру к аргументам, заданным списком.
(apply proc (list a1 ... an)) = (proc a1 ... an)
Здравствуйте, Трурль, Вы писали:
F>>Вообще, мне кажется, всё упирается в функцию apply.
F>>Опять-таки не понимаю, как она должна быть реализована... По идее она должна применять какую-либо операцию к списку.
Т>apply применяет процедуру к аргументам, заданным списком.
Т>Т>(apply proc (list a1 ... an)) = (proc a1 ... an)
Т>
Т.е. apply — не функция, а особая форма? Что-то начинает проясняться. Спасибо.
P.S. Я так понимаю, если б в scheme были бы каррированные функции, то apply легко могла быть реализована в виде функции.
Курица — это инструмент, с помощью которого одно яйцо производит другие.
Здравствуйте, Трурль, Вы писали:
Т>apply применяет процедуру к аргументам, заданным списком.
Т>Т>(apply proc (list a1 ... an)) = (proc a1 ... an)
Т>
Если быть точнее, то
(apply proc a1 ... an (list e1 ... en)) = (proc a1 ... an e1 ... en)
Здравствуйте, frogkiller, Вы писали:
F>P.S. Я так понимаю, если б в scheme были бы каррированные функции, то apply легко могла быть реализована в виде функции.
apply можно реализовать в виде функции через eval
(define (apply2 proc . lst)
(define (gather lst)
(if (null? (cdr lst))
(car lst)
(cons (car lst) (gather (cdr lst)))))
(eval (cons proc (gather lst))))
Без eval можно в виде макроса.
lomeo wrote:
> apply можно реализовать в виде функции через eval
>
> > (define (apply2 proc . lst)
> (define (gather lst)
> (if (null? (cdr lst))
> (car lst)
> (cons (car lst) (gather (cdr lst)))))
> (eval (cons proc (gather lst))))
>
>
> Без eval можно в виде макроса.
Чего-то сложновато.
Почему не (define (my-apply proc lst) (eval (cons proc lst)))?
Posted via RSDN NNTP Server 2.0