I'm new to clojure and tried to implement the some function (for some specific tests):
(my-some even? [1 2 3 4]) => true
(my-some #{3 4} [1 2 3 4]) => 3
(my-some zero? [1 2 3 4]) => nil
That's what I came up with so far:
(defn my-some [f x]
(loop [[y & t] x]
(if (empty? t) nil
(if (f y)
(f y)
(recur t)))))
I could imagine there are more idiomatic approaches. Any suggestions?
Firstly, you have a bug: [[y & t] x]
destructures x
, but the following empty?
check on t
means you are ignoring the last element in the sequence. You can see this with
(my-some even? [2])
=> nil
You can replace (if (empty? x) nil (else-form))
with when
and seq
:
(when (seq x) ...)
you can then use first
and next
to deconstruct the sequence:
(defn my-some [f x]
(when (seq x)
(if (f (first x))
(f (first x))
(recur f (rest x)))))
the call to recur
is then back into my-some
so you need to pass the predicate f
.
you can replace (if x x (else ....))
with (or x (else ...))
:
(defn my-some [f x]
(when (seq x)
(or (f (first x)) (recur f (next x)))))
you can compare this with the implementation of some