我需要编写一个scheme函数,该函数作为函数返回,然后接受另一个参数,例如列表,然后返回所需的结果。在此示例中,(c?r "arg")
将返回 - (car(cdr
- 然后随后将list参数返回2
> ((c?r "ar") '(1 2 3 4))
2
> ((c?r "ara") '((1 2) 3 4))
2
我遇到的问题是如何返回一个接受另一个arg的函数?
答案 0 :(得分:0)
以下是编写此类函数的方法:
(define (c?r cmds)
(lambda (lst)
(let recur ((cmds (string->list cmds)))
(if (null? cmds)
lst
(case (car cmds)
((#\a) (car (recur (cdr cmds))))
((#\d) (cdr (recur (cdr cmds))))
(else (recur (cdr cmds))))))))
请注意,我使用d
来表示cdr
,而不是r
(这对我来说毫无意义)。您还可以使用string-fold-right
(需要SRFI 13)更简洁地撰写此内容:
(define (c?r cmds)
(lambda (lst)
(string-fold-right (lambda (cmd x)
(case cmd
((#\a) (car x))
((#\d) (cdr x))
(else x)))
lst cmds)))
答案 1 :(得分:0)
只想添加我的演奏。使用SRFI-1。
(import (rnrs)
(only (srfi :1) fold)) ;; require fold from SRFI-1
(define (c?r str)
(define ops (reverse (string->list str)))
(lambda (lst)
(fold (lambda (x acc)
((if (eq? x #\a) car cdr) ; choose car or cdr for application
acc))
lst
ops)))
它非常类似于Chris'版本(更多以前的fold-right
),但我执行了reverse
,因此我可以在返回的过程中使用fold
。我通过查看字符来选择要调用car
或cdr
中的哪一个。
修改强>
这是一个具有更多预处理功能的替代版本。当运行#\ d时,它会使用tail-ref
和list-tail
作为快捷方式。
(define (c?r str)
(let loop ((druns 0) (ops (string->list str)) (funs '()))
(cond ((null? ops)
(let ((funs (reverse
(if (zero? druns)
funs
(cons (lambda (x)
(list-tail x druns))
funs)))))
(lambda (lst)
(fold (lambda (fun lst)
(fun lst))
lst
funs))))
((eq? (car ops) #\d) (loop (+ druns 1) (cdr ops) funs))
((= druns 0) (loop 0 (cdr ops) (cons car funs)))
(else (loop 0 (cdr ops) (cons (lambda (x)
(list-ref x druns))
funs))))))
这可以在#!球拍中更简单。我们跳过reverse
,只做(apply compose1 funs)
。
(define (c?r str)
(let loop ((druns 0) (ops (string->list str)) (funs '()))
(cond ((null? ops)
(let ((funs (if (zero? druns)
funs
(cons (lambda (x)
(list-tail x druns))
funs))))
(apply compose1 funs)))
((eq? (car ops) #\d) (loop (+ druns 1) (cdr ops) funs))
((= druns 0) (loop 0 (cdr ops) (cons car funs)))
(else (loop 0 (cdr ops) (cons (lambda (x)
(list-ref x druns))
funs))))))
答案 2 :(得分:0)
假设compose
程序:
(define (compose funs . args)
(if (null? funs)
(apply values args)
(compose (cdr funs) (apply (car funs) args))))
(compose (list cdr car) '(1 2 3 4))
=> 2
c?r
可以用compose
来定义,如此:
(define (c?r funs)
(lambda (e)
(compose
(map
(lambda (f) (if (char=? f #\a) car cdr))
(reverse (string->list funs)))
e)))
然后
((c?r "ar") '(1 2 3 4))
=> 2
((c?r "ara") '((1 2) 3 4))
=> 2