Hi J,

I don't think there is a specific function in Clojure equivalent to 
*pairwise?* but I it might be more idiomatic to use the functions available 
in clojure.core to manipulate collections.

I would implement *pairwise?* in the following way, others might suggest 
better/simpler ways though:

(defn pairwise? 
  [pred coll] 
  (->> coll 
    (partition 2 1) 
    (every? (partial apply pred))))

*partition* return a lazy sequence and *every?* stops consuming on the 
first *false* result, so this actually only process as many pairs as 
necessary.

Hope it helps,

Juan Facorro
 
On Monday, September 21, 2015 at 5:08:36 PM UTC-3, [email protected] wrote:
>
> Hey all --
>
> I recently found myself needing to check for pairwise property consistency 
> across a sequence of elements, similar in spirit to inequality checking (in 
> this case, date comparisons using clj-time *t/before?*). What I wanted 
> was to do something like:
>
> (if (t/before? date-a date-b date-c date-d)
>
>   ; elided
>   )
>
>
> ...which is symmetric to the idiomatic usage of the inequality functions 
> in clojure core (*=*, *>* and friends). Unfortunately, *t/before?* does 
> not support variadic invocation, and after reading the source behind each 
> of those functions, I discovered that they implement their own variadic 
> overloads ad hoc, and there doesn't appear to be (at least I haven't yet 
> discovered) a way to generalize pairwise property assertion over an 
> arbitrarily large sequence of things.
>
> I would previously have solved this like:
>
> (reduce (fn [_ [x y]]
>           (if (t/before? x y)
>             true
>             (reduced false))) true
>         (partition 2 1 [(t/local-date 2015 1 1) (t/local-date 2015 2 1) 
> (t/local-date 2015 3 1)]))
>
> ;-> true
>
>
> ...or even...
>
> (every? (fn [[x y]] (t/before? x y)) (partition 2 1 [(t/local-date 2015 1 1) 
> (t/local-date 2015 2 1) (t/local-date 2015 3 1)]))
>
>
> ...which is sort of cumbersome and occludes my intent. I ended up writing 
> a function to address this problem generally, and thought it might be 
> useful to others (and possibly worth including in clojure). Here it is:
>
> (defn pairwise?
>   "Returns true if every sequential pair satisfies pred; false otherwise."
>   {:inline         (fn [pred x y] `(~pred ~x ~y))
>    :inline-arities #{3}}
>   ([_ _] true)
>   ([pred x y] (pred x y))
>   ([pred x y & more]
>    (if (pairwise? pred x y)
>      (if (next more)
>        (recur pred y (first more) (next more))
>        (pairwise? pred y (first more)))
>      false)))
>
>
> ...and the test cases:
>
> (deftest pairwise?
>   (testing "Idiomatic cases"
>     (is (pairwise? > 3 2 1 0))
>     (is (pairwise? t/after? (t/local-date 2015 3 1) (t/local-date 2015 2 1) 
> (t/local-date 2015 1 1)))
>     (is (pairwise? #(= %1 (* -1 %2)) -1 1 -1 1))
>     (is (not (pairwise? = 1 1 1 2 1))))
>   (testing "Short circuits on false"
>     (is (not (apply pairwise? = (concat [2 2] (repeat 1)))))))
>
>
> It accepts as its first argument any binary predicate, and applies it to a 
> splat until the predicate returns false. The keen eye will notice it looks 
> very similar to the variadic overload of *>*, which is what I used for 
> reference. This means you can now do things like:
>
> (pairwise? t/before? (t/local-date 2015 1 1) (t/local-date 2015 2 1) 
> (t/local-date 2015 3 1))
>
> ;-> true
>
>
> ...even though *t/after?* only supports a dyadic form. This also works 
> nicely with apply to run against seqs:
>
> (apply pairwise? t/before? [(t/local-date 2015 1 1) (t/local-date 2015 2 1) 
> (t/local-date 2015 3 1)])
>
> ;-> true
>
>
> Or, for properties that aren't necessarily correlated to ordering:
>
> (pairwise? #(= %1 (* -1 %2)) -1 1 -1 1)
>
> ;-> true
>
>
> Which of course works for the inequality operators (although they 
> obviously support this natively):
>
> (pairwise? > 3 2 1 0)
>
> ;-> true
>
>
> As i said, I was unable to find anything in clojure core similar to 
> *pairwise?*, although admittedly I've only been using clojure in anger 
> now for around 4 months, so if I'm overlooking an in-built capability, 
> please set me straight.
>
> Thoughts/suggestions/amendments/corrections welcome and appreciated!
>
> Cheers,
> -J
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
  • pairwise? jnape09
    • Re: pairwise? juan.facorro

Reply via email to