我需要編寫一個方案函數,該函數返回一個函數,然後接受另一個參數,例如一個列表,然後返回所需的結果。在這個例子中(c?r "arg")
將返回 - (car(cdr
- 這隨後採取list參數返回2返回函數的Scheme函數
> ((c?r "ar") '(1 2 3 4))
2
> ((c?r "ara") '((1 2) 3 4))
2
我的問題是我怎麼能返回接受另一ARG在嬌小的功能?
我需要編寫一個方案函數,該函數返回一個函數,然後接受另一個參數,例如一個列表,然後返回所需的結果。在這個例子中(c?r "arg")
將返回 - (car(cdr
- 這隨後採取list參數返回2返回函數的Scheme函數
> ((c?r "ar") '(1 2 3 4))
2
> ((c?r "ara") '((1 2) 3 4))
2
我的問題是我怎麼能返回接受另一ARG在嬌小的功能?
這裏是你會如何寫這樣的功能:
(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)))
只想添加我的演奏與此有關。用途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)))
它非常類似於克里斯的版本(多以前fold-right
),但我做reverse
這樣我就可以在返回的過程中使用fold
。我通過查看字符來選擇car
或cdr
中的哪一個。
編輯
這裏是另一種版本更預處理。當運行#\ d's時,它使用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))))))
假定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
'列表ref'和'LIS T-tail'?不知道如何使用這些來解決這個特定的問題。我想我不明白你的意思是「壓縮」。 :-) –
@ ChrisJester-Young類似這樣的東西..在寫這篇文章之後,我想知道Racket如何實現'compose1' – Sylwester
@Sylwester它大致等於'(define(my-compose1。fs) (foldr(lambda(fg) (lambda(x)(f(gx))))身份fs))' – Wes