Clojure - someはfalseじゃなくてnilを返す
JavaScriptのArray.some感覚で使っていたら間違えたのでメモ。
Returns the first logical true value of (pred x)
Returns the first logical true value of (pred x) for any x in coll,
else nil. One common idiom is to use a set as pred, for example
this will return :fred if :fred is in the sequence, otherwise nil:
(some #{:fred} coll)
条件に一致する場合に何を返すかはpredに依存します。
例えばtrueを返すpredならtrueです。
sample=> (some true? [false true false]) true sample=> (some even? [1 3 4 6 7]) true
値を返す場合は、最初に一致した値が返ります。
(trueを返している場合も結局は同じことですが)
sample=> (some #(if (even? %) %) [1 3 4 6 7]) 4
else nil
すべての要素がpredに失敗した場合はnilが返ります。
sample=> (some even? [1 5 7]) nil
someはpredicateではないからです。
関数名に「?」が付いていないのもそのためです。
後述のフォーラムに説明が書かれています。
一致したらtrue、一致しなかったらfalseを返したい
some-fnを使う
sample=> ((some-fn even?) 1 5 7) false sample=> (apply (some-fn even?) [1 5 7]) false
ただやはりpredに依存するので注意。
sample=> ((some-fn #(if (even? %) %)) 1 5 7) nil sample=> ((some-fn #(if (even? %) %)) 1 5 7 8) 8
not-every?やnot-any?を使う方法も良いと思います。
参考
falseを返さないことでミスったのと、
「何でsomeは?なしでnot-every?とかは?付いているんだ」と思ったことがきっかけ。
フォーラムにそのまんま書いてありました。
Is there a reason why 'some' returns "nil" instead o "false"?