Currying a function n times in Scheme

落花浮王杯 提交于 2019-12-20 02:28:23

问题


I'm having trouble figuring out a way to curry a function a specified number of times. That is, I give the function a natural number n and a function fun, and it curries the function n times. For example:

(curry n fun)

Is the function and a possible application would be:

(((((curry 4 +) 1) 2) 3) 4)

Which would produce 10.

I'm really not sure how to implement it properly. Could someone please give me a hand? Thanks :)


回答1:


You can write your own n-curry procedure by repeatedly calling curry:

(define (n-curry n func)
  (let loop ([i 1] [acc func])
    (if (= i n)
        acc
        (loop (add1 i) (curry acc)))))

If you're in Racket, it can be expressed a bit simpler using a for/fold iteration:

(define (n-curry n func)
  (for/fold ([acc func])
    ([i (in-range (sub1 n))])
    (curry acc)))

Anyway use it like this:

(((((n-curry 4 +) 1) 2) 3) 4)
=> 10



回答2:


;;; no curry
;;; (Int, Int, Int) => Int

(define sum
  (lambda (x y z)
    (+ x y z) ) )

(sum 1 2 3)

;;; curry once
;;; (Int) => ((Int x Int) => Int)

(define sum
  (lambda (x)
    (lambda (y z)
      (+ x y z) ) ) )

(define sum+10 (sum 10))

(sum+10 10 20)

;;; curry 2 times
;;; (Int) => (Int => (Int => Int) )

(define sum
  (lambda (x)
    (lambda (y)
      (lambda (z)
        (+ x y z) ) ) ) )

(define sum+10+20 ((sum 10) 20))

(sum+10+20 30)

;;; Now we will generalize, starting from these examples:

(define (curry n f)
  (if (= n 0)
      (lambda (x) x)
      (lambda (x) (f ((curry (- n 1) f) x)))))

;;;Example: apply 11 times the function 1+ on the initial number 10 , results 21:

((curry 11 (lambda (x) (+ x 1))) 10)


来源:https://stackoverflow.com/questions/13552597/currying-a-function-n-times-in-scheme

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!