[plt-scheme] idiomatic way to split a list into first, middle, last?
John Clements wrote:
> Here's what I want:
>
> (match l
> [`(,first ,middle ... ,last)
> `(,(first-proc first) ,@(map middle-proc middle) ,(last-proc last))])
>
>
> ... but I can't have that, apparently. Here are two ugly solutions.
> Is there a better one?
Long ago I wrote a srfi-42 generator that generates all pairs of a list
[perhaps we could put it in (lib "42.ss" "srfi") ? ]
> (list-ec (:pairs p (list 1 2 3 4)) p)
((1 2 3 4) (2 3 4) (3 4) (4))
Given that generator, one can write
(define (map/last f f-last xs)
(list-ec (:pairs p xs)
((if (null? (cdr p)) f-last f)
(car p))))
(map/last + - (list 1 2 3 4 5))
; => (1 2 3 4 -5)
which is reasonably readable, although I too would
prefer your extension wish for match.
The entire snippet:
(require (lib "42.ss" "srfi"))
(define-syntax :pairs
(syntax-rules ()
((:pairs cc p l)
(:do cc ((p l)) (not (null? p)) ((cdr p))))))
(define (map/last f f-last xs)
(list-ec (:pairs p xs)
(begin
((if (null? (cdr p)) f-last f)
(car p)))))
(map/last + - (list 1 2 3 4 5))
--
Jens Axel Søgaard