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)