Takes a set of functions and returns a fn that is the composition
of those fns. The returned fn takes a variable number of args,
applies the rightmost of fns to the args, the next
fn (right-to-left) to the result, etc.
user=> (def negative-quotient (comp - /)) #'user/negative-quotient user=> (negative-quotient 8 3) -8/3 user=> (def concat-and-reverse (comp (partial apply str) reverse str)) #'user/concat-and-reverse user=> (concat-and-reverse "hello" "clojuredocs") "scoderujolcolleh"
;; make a struct 'goods'. it assumes that every goods has
;; its id number and price.
(defstruct goods :id :price)
;; generate data.
(def data (map #(struct goods %1 %2)
(shuffle (range 0 10)) (shuffle
(into (range 100 500 100)
(range 100 500 100)))))
(defn comp-goods-price
"a compare function by :price of the struct 'goods.' the sort order
is that the lower price is superior to the higher one and if the
price is same, the lower id is superior to the higher one."
[el1 el2]
(if (or (< (:price el1) (:price el2))
(and (= (:price el1) (:price el2))(< (:id el1) (:id el2))))
true
false))
user> data
({:id 1, :price 300} {:id 6, :price 100} {:id 3, :price 100} {:id 4, :price 400} {:id 0, :price 300} {:id 2, :price 200} {:id 5, :price 200} {:id 8, :price 400})
user> (sort (comp comp-goods-price) data)
({:id 3, :price 100} {:id 6, :price 100} {:id 2, :price 200} {:id 5, :price 200} {:id 0, :price 300} {:id 1, :price 300} {:id 4, :price 400} {:id 8, :price 400})
user> (sort-by :price < data) ; compare this with the above.
({:id 6, :price 100} {:id 3, :price 100} {:id 2, :price 200} {:id 5, :price 200} {:id 1, :price 300} {:id 0, :price 300} {:id 4, :price 400} {:id 8, :price 400})
;; Yet another example of 'comp' by PriorityBlockingQueue.
user> (import [java.util.concurrent PriorityBlockingQueue])
java.util.concurrent.PriorityBlockingQueue
user> (def pqdata (new PriorityBlockingQueue 8
(comp comp-goods-price)))
#'user/pqdata
user> (doseq [x data]
(.add pqdata x))
nil
user> (dotimes [_ 8]
(println (.poll pqdata)))
{:id 3, :price 100}
{:id 6, :price 100}
{:id 2, :price 200}
{:id 5, :price 200}
{:id 0, :price 300}
{:id 1, :price 300}
{:id 4, :price 400}
{:id 8, :price 400}
nil
user>
(defn comp
"Takes a set of functions and returns a fn that is the composition
of those fns. The returned fn takes a variable number of args,
applies the rightmost of fns to the args, the next
fn (right-to-left) to the result, etc."
{:added "1.0"}
([f] f)
([f g]
(fn
([] (f (g)))
([x] (f (g x)))
([x y] (f (g x y)))
([x y z] (f (g x y z)))
([x y z & args] (f (apply g x y z args)))))
([f g h]
(fn
([] (f (g (h))))
([x] (f (g (h x))))
([x y] (f (g (h x y))))
([x y z] (f (g (h x y z))))
([x y z & args] (f (g (apply h x y z args))))))
([f1 f2 f3 & fs]
(let [fs (reverse (list* f1 f2 f3 fs))]
(fn [& args]
(loop [ret (apply (first fs) args) fs (next fs)]
(if fs
(recur ((first fs) ret) (next fs))
ret))))))
Comments top
No comments for comp. Log in to add a comment.