some-fn

added
1.3

ns
clojure.core

type
function

(some-fn p) (some-fn p1 p2) (some-fn p1 p2 p3) (some-fn p1 p2 p3 & ps)

Takes a set of predicates and returns a function f that returns the first logical true value
returned by one of its composing predicates against any of its arguments, else it returns
logical false. Note that f is short-circuiting in that it will stop execution on the first
argument that triggers a logical true result against the original predicates.

                
user=> ((some-fn even?) 1)
false
user=> ((some-fn even?) 2)
true
user=> ((some-fn even?) 1 2)
true

            
                ;; `some-fn` is useful for when you'd use `some` (to find out if any
;; values in a given coll satisfy some predicate), but have more than
;; one predicate. For example, to check if any values in a coll are
;; either even or less than 10:

(or (some even? [1 2 3])
    (some #(< % 10) [1 2 3]))

;; but `some-fn` can save you some duplication here:

((some-fn even? #(< % 10)) 1 2 3)

;; Minor note: the former returns nil if it doesn't find
;; what it's looking for. The latter returns false.
            
                ;;; http://en.wikipedia.org/wiki/Fizz_buzz
(def fizzbuzz
  (some-fn #(and (= (mod % 3) 0) (= (mod % 5) 0) "FizzBuzz")
           #(and (= (mod % 3) 0) "Fizz")
           #(and (= (mod % 5) 0) "Buzz")
           str))

(run! println (map fizzbuzz (range 1 18)))

1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
            
                ;; Here's an easy way to apply several functions in succession to the same
;; value and get the first true result. Note the double parentheses at the
;; beginning: because some-fn returns a function, you have to apply it.

((some-fn :a :b :c :d) {:c 3 :d 4})
;=> 3

;; Here's how to do the same thing but with a vector of functions.  Note
;; the 'apply' as well as the double parentheses, since you have to make
;; some-fn take its arguments from the vector.

(def parsers
  [parse-custom-command
   parse-basic-command
   parse-weird-command
   reject-command])

((apply some-fn parsers) text-from-user)

;; Each element of parsers is a function that returns a data structure if
;; it successfully parses its argument or nil if it fails. reject-command
;; always succeeds, returning a representation of an error.

;; Note the technique of putting a catch-all function for errors last.