3

I'm currently preparing for an exam and thought that writing foldl with foldr would be a nice question to get tested on.

Anyways, I know that (foldl f base lst) returns (f xn (f x(n-1) . . . (f x1 base) with the lst being (x1 . . . xn)

So what I currently have is this:

(define (foldl/w/foldr f base lst)

(foldr (lambda (x y) (f y (f x base))) base lst)))

This doesn't quite work, and I am unsure on how to proceed.

Sébastien
  • 11,860
  • 11
  • 58
  • 78
Syn F G
  • 33
  • 3

2 Answers2

4

Using Haskell's documentation as a starting point (as mentioned by @soegaard in the comments), here's a working solution for this problem, using Racket syntax:

(define (foldl/w/foldr f base lst)
  ((foldr (λ (ele acc) (λ (x) (acc (f ele x))))
          identity
          lst)
   base))

For example:

(foldl/w/foldr cons '() '(1 2 3 4 5))
=> '(5 4 3 2 1)
(foldl/w/foldr + 0 '(1 2 3 4 5))
=> 15

The key to understand this is that we're accumulating lambdas with delayed computations, not values, and at the end we invoke all the chain of lambdas passing the base value to start the computation. Also notice that the identity procedure is used as the first accumulator, and we accumulate more lambdas on top of it. For instance, this call:

(foldl/w/foldr + 0 '(1 2))

Will be evaluated as follows:

((lambda (x)              ; this lambda is the value returned by foldr
   ((lambda (x)
      (identity (+ 1 x))) ; add first element in the list (this gets executed last)
    (+ 2 x)))             ; add second element in the list (this gets executed first)
 0) ; at the end, we invoke the chain of lambdas starting with the base value
=> 3
Óscar López
  • 232,561
  • 37
  • 312
  • 386
1

I am not a Lisp programmer, so this maybe not syntactically perfect, but it will be something like

foldl f a l = (foldr (lambda (h p) (lambda (x) (p (f x h))) )
                     l
                     (lambda (x) (x))
                     a))

The trick is to accumulate function instead of result value. I am applying four arguments to foldr, because in this case regular foldr returns function, that will take "a" as an argument.

radrow
  • 6,419
  • 4
  • 26
  • 53