変換関数

変換関数はクエリ内で値を変換してその結果をパターン変数に束縛するのに使用できる副作用のない純粋関数またメソッドです。 たとえば、:db.type/instant型の:person/bornという属性があるとします。与えられた誕生日を使って、おおよその年齢を計算するのは簡単です。

(defn age [birthday today]
  (quot (- (.getTime today)
           (.getTime birthday))
        (* 1000 60 60 24 365)))

この関数を使って、クエリの中で人物の年齢を計算することができます。

[:find ?age
 :in $ ?name ?today
 :where
 [?p :person/name ?name]
 [?p :person/born ?born]
 [(tutorial.fns/age ?born ?today) ?age]]

変換関数句は[(<fn> <arg1> <arg2> ...) <result-binding>]の形をとります。 <result-binding>3章でみたのと同じ束縛形式をとることができます。

  • スカラ: ?age
  • タプル: [?foo ?bar ?baz]
  • コレクション: [?name ...]
  • リレーション: [[?title ?rating]]

変換関数は入れ子にできないことに注意。下記のように書くことはできません。

[(f (g ?x)) ?a]

代わりに、中間結果を一時的なパターン変数に束縛する必要があります。

[(g ?x) ?t]
[(f ?t) ?a]

年齢で人物を検索しなさい。与えられた誕生日と今日を表す日付を使って年齢を算定するtutorial.fns/age関数を用いなさい。

クエリ:[ 答を見る ]

入力値1:

入力値2:

Bruce Willisより若い人の人名と年齢を検索しなさい。

クエリ:[ 答を見る ]

入力値1:

誕生日のパラドックスによると、部屋の中に23人いれば誕生日が同じ人が入る確率が50%になると言われている。誕生日が同じ人を見つけるクエリを書きなさい。<述語を名前に使って重複した答えを除きなさい。Javaのjava.util.Dateパッケージに含まれている廃止予定の.getDate.getMonthを使ってよいこととする。

クエリ:[ 答を見る ]