August 13, 2018

4clojure 158 - Decurry

Write a function that accepts a curried function of unknown arity n. Return an equivalent function of n arguments. You may wish to read this.

(ns live.test
  (:require [cljs.test :refer-macros [deftest is run-tests]]))
  
; jafingerhut's solution:

;; Note: This function does not return a function that takes only
;; exactly n arguments, the number of arguments expected by the
;; curried function.  Instead it takes a variable number of arguments,
;; and keeps applying the curried function on successive arguments
;; until the arguments run out.
 
;; I don't see how to literally do what the problem is asking for,
;; especially if we cannot assume what type of arguments the functions
;; take, and then make trial calls to the functions, and assume that
;; they are never intended to return functions.
 
(defn decurry [f]
  (fn [& args]
    (reduce (fn [f a]
              (f a))
            f args)))

(deftest decurry-test
  (is (= 10 ((decurry (fn [a]
             (fn [b]
               (fn [c]
                 (fn [d]
                   (+ a b c d))))))
       1 2 3 4)))
  (is (= 24 ((decurry (fn [a]
             (fn [b]
               (fn [c]
                 (fn [d]
                   (* a b c d))))))
       1 2 3 4)))
  (is (= 25 ((decurry (fn [a]
             (fn [b]
               (* a b))))
       5 5)))
  (is (= 25 ((decurry (fn [a]
             (fn [b]
               (* a b))))
       5 5))))
 
(run-tests)
Tags: coding exercises KLIPSE 4clojure Clojure