[plt-scheme] idiomatic way to split a list into first, middle, last?

From: Jens Axel Søgaard (jensaxel at soegaard.net)
Date: Fri Jan 6 09:52:52 EST 2006

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




Posted on the users mailing list.