7

I have this curry function:

(define curry
(lambda (f) (lambda (a) (lambda (b) (f a b)))))

I think it's like (define curry (f a b)).

my assignment is to write a function consElem2All using curry,which should work like

(((consElem2All cons) 'b) '((1) (2 3) (4)))
>((b 1) (b 2 3) (b 4))

I have wrote this function in a regular way:

(define (consElem2All0 x lst) 
  (map (lambda (elem) (cons x elem)) lst))

but still don't know how to transform it with curry. Can anyone help me?

thanks in advance

bearzk

starblue
  • 55,348
  • 14
  • 97
  • 151
bearzk
  • 685
  • 3
  • 7
  • 22

4 Answers4

4

You should begin by reading about currying. If you don't understand what curry is about, it may be really hard to use it... In your case, http://www.engr.uconn.edu/~jeffm/Papers/curry.html may be a good start.

One very common and interesting use of currying is with functions like reduce or map (for themselves or their arguments).

Let's define two currying operators!

(define curry2 (lambda (f) (lambda (arg1) (lambda (arg2) (f arg1 arg2)))))
(define curry3 (lambda (f) (lambda (arg1) (lambda (arg2) (lambda (arg3) (f arg1 arg2 arg3))))))

Then a few curried mathematical functions:

(define mult (curry2 *))
(define double (mult 2))

(define add (curry2 +))
(define increment (add 1))
(define decrement (add -1))

And then come the curried reduce/map:

(define creduce (curry3 reduce))
(define cmap (curry2 map))

Using them

First reduce use cases:

(define sum ((creduce +) 0))
(sum '(1 2 3 4)) ; => 10

(define product (creduce * 1))
(product '(1 2 3 4)) ; => 24

And then map use cases:

(define doubles (cmap double))
(doubles '(1 2 3 4)) ; => (2 4 6 8)

(define bump (cmap increment))
(bump '(1 2 3 4)) ; => (2 3 4 5)

I hope that helps you grasp the usefulness of currying...

jotaen
  • 6,739
  • 1
  • 11
  • 24
Nowhere man
  • 5,007
  • 3
  • 28
  • 44
  • 1
    Nitpicks: Your add definition is missing its closing parenthesis and your (creduce + 0) calls should be ((creduce +) 0) as creduce expects one argument. – Julien Rousseau Aug 04 '13 at 13:29
  • I usually forbid myself to post code I didn't copy/pasted from a successful running code. Nice catch! – Nowhere man Aug 04 '13 at 22:56
  • @Nowhereman Hi, the link given in your answer seems to be down. Could you point out to another resource for learning currying? – danny Sep 19 '16 at 01:57
  • @dannny It is stil reachable in the WayBack Machine, though: https://web.archive.org/web/20140330131408/http://www.engr.uconn.edu/~jeffm/Papers/curry.html – Nowhere man Sep 19 '16 at 08:26
1

So your version of curry takes a function with two args, let's say:

(define (cons a b) ...)

and turns that into something you can call like this:

(define my-cons (curry cons))
((my-cons 'a) '(b c)) ; => (cons 'a '(b c)) => '(a b c)

You actually have a function that takes three args. If you had a curry3 that managed 3-ary functions, you could do something like:

(define (consElem2All0 the-conser x lst) ...)

(like you did, but allowing cons-like functions other than cons to be used!)

and then do this:

(define consElem2All (curry3 consElem2All0))

You don't have such a curry3 at hand. So you can either build one, or work around it by "manually" currying the extra variable yourself. Working around it looks something like:

(define (consElem2All0 the-conser)
  (lambda (x lst) ...something using the-conser...))
(define (consElem2All the-conser)
  (curry (consElem2All0 the-conser)))

Note that there's one other possible use of curry in the map expression itself, implied by you wrapping a lambda around cons to take the element to pass to cons. How could you curry x into cons so that you get a one-argument function that can be used directly to map?...

Owen S.
  • 7,665
  • 1
  • 28
  • 44
0

Perhaps better use a generalized version:

(define (my-curry f)
  (lambda args
    (cond ((= (length args) 1)
             (lambda lst (apply f (cons (car args) lst))))
          ((>= (length args) 2)
             (apply f (cons (car args) (cdr args)))))))
Gwang-Jin Kim
  • 9,303
  • 17
  • 30
-1
(define (consElem2All0 x lst) 
  (map ((curry cons) x) lst))
Joe D
  • 2,855
  • 2
  • 31
  • 25