Scalaz に memo化の機能があるらしいので使ってみた

(自分の中では) "メモ化"って

純粋*1な関数の結果を、一度実行した場合にキャッシュとして保持しておいて、2回目以降はキャッシュしておいた値を返す。

くらいな理解です。で、Scalaでのメモ化とかちょっと前に流行って、以下のakihiroさんのものとか(自分の中で)有名なわけです。*2

akihiroさんがあれ書いたときとか、自分のTLではメモ化がちょっと流行ったわけですが、「実はScalazにあるよ!」的なことを誰もいってなかった気がする*3のでちょっとだけ紹介してみます。

https://github.com/scalaz/scalaz/blob/6.0.3/core/src/main/scala/scalaz/Memo.scala
http://scalaz.github.com/scalaz/scalaz-2.9.1-6.0.2/doc.sxr/scalaz/Memo.scala.html


使ってみたはいいけど、まだ完全に使い方わかってないし、使いづらい部分があるんですがががが(´・ω・`)

例えば、このarrayMemoって、型引数にAnyValのIntやLongを渡せないけどなんで・・・?とか


まぁとにかくこれ以上ごちゃごちゃいっても仕方ないので、とりあえずサンプル(´・ω・)っ


2回目以降は、一瞬で返ってきているのがわかりますね。最初、 Memos がなんで trait で object じゃないのかなぁー?とわからなくて、いちいち、

val m = new Memos{}

と、無名クラスでインスタンス生成していたのですが、これって以下の場所で

https://github.com/scalaz/scalaz/blob/6.0.3/core/src/main/scala/scalaz/Scalaz.scala#L44

Scalaz の singleton object が Memos を継承しているので、

import scalaz._
import Scalaz._

とやるだけで、直接 arrayMemo や doubleArrayMemo なども、グローバルな関数のような感覚で呼べるわけですね。Scalazはだいたいこのパターンで全体が作られているのに、すぐに気づかなかった自分はまだまだ修行が足りない・・・(´・ω・`)

*1:引数同じならば必ず同じ結果を返す

*2: しかしこれ書くために、改めてakihiroさんの読みなおしたけれど、再帰の関数のメモ化とか、全然次元が違いますね・・・。たぶんScalazのやつ使っても、akihiroさんがやったようなことはできないっぽい・・・?

*3:言ってたらごめんなさい