My apologies for misrepresenting Haskell's nubBy: On 22 February 2010 19:15, Michał Marczyk <michal.marc...@gmail.com> wrote: > The Haskell approach is to have two functions, nub and nubBy, which > perform the task of distinct and the task of distinct with a > user-provided keyfn, respectively.
Actually nubBy takes a binary function as its first argument and performs equality comparisons of each successive element to each of the elements collected into the result list using that function. A corresponding Clojure function: (defn distinct-by "A version following Haskell's nubBy." [f coll] (let [step (fn step [xs seen] (lazy-seq ((fn [[x :as xs] seen] (when-let [s (seq xs)] (if (some #(f x %) seen) (recur (rest s) seen) (cons x (step (rest s) (conj seen x)))))) xs seen)))] (step coll #{}))) Here's one example of use: user> (distinct-by #(= (class %1) (class %2)) [1 2 3 :a :b :c 'a 'b 'c]) (1 :a a) And here's a Clojure version of the coolest Haskell one-liner I've ever seen: user> (take 10 (distinct-by #(< 1 (gcd %1 %2)) (iterate inc 2))) (2 3 5 7 11 13 17 19 23 29) The alternative is to use a unary keyfn-based approach as I originally suggested. This would work like so: (defn distinct-by "NB. this isn't like Haskell's nubBy. f is supposed to be unary." [f coll] (let [step (fn step [xs seen] (lazy-seq ((fn [[x :as xs] seen] (when-let [s (seq xs)] (if (some #(f x %) seen) (recur (rest s) seen) (cons x (step (rest s) (conj seen (f x))))))) xs seen)))] (step coll #{}))) user> (distinct-by class [1 2 3 :a :b :c 'a 'b 'c]) (1 :a a) Now I'm not really sure which one is more deserving of being called distinct-by... Sincerely, Michał -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en