定義済みの関数を無名関数に変えたい。それ、どうやったら出来るの?次の関数は、シーケンスから最後の要素を返します。
(defn lastt [l]
(cond
(nil? (next l)) l
:else
(lastt (next l))))
形にするにはどうすればいいfn
ですか?
PS: 関数については知っていlast
ますが、これは単なる演習です。
定義済みの関数を無名関数に変えたい。それ、どうやったら出来るの?次の関数は、シーケンスから最後の要素を返します。
(defn lastt [l]
(cond
(nil? (next l)) l
:else
(lastt (next l))))
形にするにはどうすればいいfn
ですか?
PS: 関数については知っていlast
ますが、これは単なる演習です。
まず、その関数は、最後の項目を含むリストを返します。最後の項目だけを返すように定義を変更します。
(defn lastt [l]
(cond
(nil? (next l)) (first l)
:else (lastt (next l))))
簡単にするために、 で2 回let
呼び出しているため、バインディングを使用します。next
l
(defn lastt [l]
(let [n (next l)]
(cond
(nil? n) (first l)
:else (lastt n))))
次に行うことは、最終呼び出しを代わりlastt
に使用するように置き換えることですrecur
(defn lastt [l]
(let [n (next l)]
(cond
(nil? n) (first l)
:else (recur n))))
そして、私はそれを
#(let [n (next %)]
(cond
(nil? n) (first %)
:else (recur n)))
そして、破壊を使用してさらに単純化できることに気付きました:)
#(let [[h & t] %]
(cond
(nil? t) h
:else (recur t)))
更新しました
cond
ブランチは 2 つしかないため、 は必要ありません。短縮形fn
の代わりにを使用すると、のパラメータで分解を行うことができ、関数全体がもう少し簡潔になります。#
fn
(fn [[h & t]]
(if (empty? t) h
(recur t)))
私はクロージャーというよりはスキーマ/CLer ですが、(defn f [args] body)
ほとんどが の構文糖衣のように見えます(def f (fn f ([args] body)))
。この場合、 を省略lastt
して無名関数として記述できますdef
。
(fn lastt
([l] (cond
(nil? (next l))
l
:else
(lastt (next l)))))
再帰なのでlastt
、ボディ内でバインドする名前を指定する必要があります。