Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Lisp have something like Haskell's takeWhile function?

I'm new to Common Lisp. In Haskell, you can do a little something like this:

Prelude> takeWhile (<= 10) [k | k <- [1..]]
[1,2,3,4,5,6,7,8,9,10]

Is this possible in Lisp? Not necessarily with an infinite list, but with any list.

like image 678
Mike Avatar asked May 29 '11 13:05

Mike


1 Answers

You could use LOOP:

(setq *l1* (loop for x from 1 to 100 collect x))
(loop for x in *l1* while (<= x 10) collect x)

If you really need it as a separate function:

(defun take-while (pred list)
  (loop for x in list
        while (funcall pred x)
        collect x))

And here we are:

T1> (take-while (lambda (x) (<= x 10)) *l1*)
(1 2 3 4 5 6 7 8 9 10)

But if we compare:

(loop for x in *l1* while (<= x 10) collect x)
(take-while (lambda (x) (<= x 10)) *l1*)

I think I would just stick with loop.

For infinite sequences, you could take a look at Series:

T1> (setq *print-length* 20)
20
T1> (setq *l1* (scan-range :from 1))
#Z(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ...)
T1> (until-if (lambda (x) (> x 10)) *l1*)
#Z(1 2 3 4 5 6 7 8 9 10)
like image 128
danlei Avatar answered Sep 21 '22 23:09

danlei