最近HamstersっていうScalaライブラリを発見しました。関数型っぽいコンテナや機能を提供するものなのですが、非常にコンパクトでなおかつ関数型プログラミングに慣れていなくても簡単に使えるというものです。
使い方はREADMEを見ればだいたいわかると思いますが、以下のような機能があるようです。
- Validation
- OK/KO Monads
- Monad transformers
- HLists
- Union types
ひとつずつ見ていきましょう。
ValidationとOK/KO
Validation
はEither
のリストを格納するコンテナ、OK
/ KO
はright-biasなEither
のエイリアスで、組み合わせて使います。
こんな感じで全部の結果を保持するか、
val e1 = OK(1) val e2 = KO("error 1") val e3 = KO("error 2") val validation = Validation(e1, e2, e3) val failures = validation.failures //List[String] : List("error 1", "error 2") val successes = validation.successes //List[Int] : List(1)
for式で失敗したところで終了するようにできます。
// Stop at first error for { v1 <- e1 v2 <- e2 v3 <- e3 } yield(s"$v1-$v2-$v3") //KO("nan")
Monad transformers
ネストしたモナドをひっくり返して扱うことができるやつです。非同期処理を記述するためにFuture
を多用しているとお世話になる機会が多いと思います。FutureOption
とFutureEither
が用意されています。
def foa: Future[Option[String]] = Future(Some("a")) def fob(a: String): Future[Option[String]] = Future(Some(a+"b")) val composedAB: Future[Option[String]] = for { a <- FutureOption(foa) ab <- FutureOption(fob(a)) } yield ab
型は決め打ちですが、その分あまり難しいことを考えずに使えるんじゃないでしょうか。実装も簡単なので足りないものは自分で作るのもありなんじゃないかと思います。
HLists
要素毎に型を持てるリストです。たくさん値を格納できる可変長のタプルみたいな感じで使えます。フレームワークなんかでは23個以上のパラメータを渡す必要のある関数の引数(23個以上のプロパティを持つケースクラスのapply
メソッドを関数に変換したい場合とか)にも使われますね。
(2.0 :: "hi" :: HNil).filter{ case s: String if s.startsWith("h") => true case _ => false } //"hi" :: HNil
Union types
複数の型のどれかっていう型を表現できます。たとえばString
もしくはInt
を返すメソッドならこんな感じ。
val stringOrIntType = new Union2Type[String, Int] import stringOrIntType._ def stringOrInt(x: Int): Union2[String, Int] = { if(x == 0) "0" else 1 } stringOrInt(0) match { case Union2(Some(x), _) => println("String") case Union2(_, Some(x)) => println("Int") }
うーん、これはちょっと厳しいですかね…。実態は単純に各型の要素をOption
で保持しているだけです。一応Union2
からUnion5
まで用意されています。
Scalazのような本格的な関数型ライブラリと違って型クラスで拡張できるというようなものではないのですが、使い方も簡単ですしフットプリントも小さいので「Scalaコードをちょっと便利に記述したい」というくらいのモチベーションであればこのくらいのライブラリがちょうどいいのかもしれません。ただ、そういう動機で使うライブラリであれば個人的にはローンパターンとかシンタックスシュガーみたいのもあるといいなぁと思ったりします。
なお、拡張ライブラリとしてTwitter UtilをサポートするものやHListを強化するものなんかも作っているみたいです。