1

Racket has only foldl and foldr, which require initial value. Haskell in addition has foldl1 and foldr1, which instead of applying a function on the initial value and the first element, applies to first and second element. Currently i implemented them as:

(define (foldl1 f xs)
  (foldl f (first xs) (rest xs)))

Is there a better way?

Mirzhan Irkegulov
  • 17,660
  • 12
  • 105
  • 166
  • No, I don't know a better way. By the way, although you probably already know this, [`foldl` is not exactly the same in Racket and Haskell](http://stackoverflow.com/questions/8778492/why-is-foldl-defined-in-a-strange-way-in-racket?). – Greg Hendershott Mar 24 '14 at 12:56

2 Answers2

2

There is a better way, just (require srfi/1) and use reduce and reduce-right. :-D

C. K. Young
  • 219,335
  • 46
  • 382
  • 435
1

What you are describing looks like reduce in CL. Your procedure looks ok except it would fail if the list is empty.

Be aware that first and rest are not the same as car and cdr since they only work on proper lists. eg.

(first '(a b c d e . f))
;;==> 
;;first: contract violation
;;  expected: (and/c list? (not/c empty?))
;;  given: '(a b c d e . f)

Now. For racket to signal here it must have traversed the whole list to make sure it ends with null and since it didn't it signaled an error. I did a small test and found out that sorting a 2 million list used 32% more time with first/rest.

Sylwester
  • 47,942
  • 4
  • 47
  • 79