ScalazのAlign

Scalaz7.1.0-M3でました。開発中のマイルストーン版なので、7.0.xとも7.1.0-M2などともバイナリ互換性はありません。
気がついたら、7.1.0-M2から7.1.0-M3の半分以上のcommitが自分です。なので、おそらく誰よりも最近の変更点に詳しいです。
あとこんなこと↓もありました


7.1.0-M3での変更点は、細かいものを含めると大量にありますが
https://github.com/scalaz/scalaz/wiki/7.1.0-M3
今回は、7.1.0-M3から入ったAlignというtypeclassについて簡単に紹介します。*1


Scala標準ライブラリのコレクションには、zipとzipAllというメソッドがあります。

scala> List(1,2) zip List("a", "b", "c" ,"d")
res0: List[(Int, String)] = List((1,a), (2,b)) // 長さが短いほうに合わせるので、"c"と"d"は消える。

scala> List(1,2).zipAll(List("a", "b", "c" ,"d"), 0, "z")
res1: List[(Int, String)] = List((1,a), (2,b), (0,c), (0,d)) 
// zipAllは、長さが合わなかった場合、2番目の引数もしくは3番目の引数で全部埋める

Alignを使う場面としては、zipやzipAllと似ています。Alignのtypeclassには、いくつかメソッドがありますが、基本的にはalignかalignWithを使うことになると思います。

scala> List(1,2) align List("a", "b", "c" ,"d")
res0: List[scalaz.\&/[Int,String]] = List(Both(1,a), Both(2,b), That(c), That(d))

zipは「長い方を切り捨てる」、zipAllは「与えられた引数で埋め合わせる」でしたが、alignは
「Tuple2の代わりに、This,That,Bothという3つの状態のどれかを表すTheseというcase classを使う」
というだけです。

場合によっては、zipやzipAllより使いやすいかもしれません。

*1:ちなみに、あまり使われてなさそうですが、Haskellにもほぼ同様のものがあります http://hackage.haskell.org/package/these-0.3 https://github.com/isomorphism/these