本当は怖いHPC

HPC屋の趣味&実益ブログ

fnとpartialとcomp

clojureでは、高階関数が重要で、特に関数を作り出す構文・関数・マクロをうまく使いこなせば、短く明瞭なプログラムを書くことができる。

Clojureにおいては、関数を作り出し適用するための仕組みとしてfn, #(), partial, compがある。これらの操作についてまとめてみる。

fnと#()

一番基本となるのがfnおよび#()だ。SchemeCommon Lispにおけるlambda,つまり無名関数を作り出す。fn と #() は同じ意味だ。

user> (filter #(zero? (rem % 3)) (range 30))
(0 3 6 9 12 15 18 21 24 27)
user> (filter (fn [n] (zero? (rem n 3))) (range 30))
(0 3 6 9 12 15 18 21 24 27)

partial

関数の部分適用のためのpartial関数がある。これを使うと、Haskellの部分適用と同じことができる。

user> (map (partial * 3) (range 10))
(0 3 6 9 12 15 18 21 24 27)

つまり (* 3 _) という形の式を考え、 _ の部分を引数として取る1引数の関数が生成される。#(* 3 %) と同じ意味だがより簡潔に書くことができる。

comp

次にcomp。compはcompositionの略、つまり関数合成だ。Haskellでいう "." (ドット)に相当する(たぶん)。次の式は、(range 10)のそれぞれの値から1を引いて2倍し、文字列として返す。

user> (map (comp str (partial * 2) dec) (range 10))
("-2" "0" "2" "4" "6" "8" "10" "12" "14" "16")

(comp str (partial * 2) dec) までが1つの関数を表す。

【広告】