9
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Cats と Scalaz の型クラスの違いメモ

Posted at

Scalaz を使うことになったので、そこそこ使いなれた Cats との違いを、特に型クラスに着目して比べてみる。

はじめに

自分が本格的に Scala を始めたときすでに Cats が普及し始めていて、仕事でも Cats から入ったわりと新参なので、Scalaz 自体はほとんど触ったことがない。ただ『FP in Scala』辺りは繰り返し読んでいるし、いろいろ知見の詰まった歴史のある老舗ライブラリということは知っているので、この際、ある程度使えるようにしておきたい。

そこで、この記事では Cats を起点にして違いをみてみる。Cats の ○○ が Scalaz ではどうなるか?という方向で観察するので、ベテラン Scala プログラマには順序が逆に思えるかもしれない。

方針

下図のクラス群を対象とする。
cats_scalaz_typeclasses_diff2.png

Cats サイトの型クラス図の、FunctorMonad を含む core の階層をベースにして、 『FP for Mortals』 に掲載されている Scalaz の型クラス階層と対比してみた。ただし、、、

  • Cats 側の Unordered*Commutative* は省略した。
  • 現状のソースとあっていない部分は、図を修正した。
  • Cats は 1.6.0、Scalaz は 7.2.27 を参考にした。

各型クラスのメモ

函手と○変

  • Invariant: Scalaz では InvariantFunctor。メソッドも imapxmap になる。
  • Functor: だいたい同じ。
  • Covariant: Invariant から継承した imap を除いてだいたい同じ。

Foldable 系

  • Foldable: だいたい同じ。
  • Traverse: だいたい同じ。
  • Reducible: Scalaz では Foldable1で、メソッドも reducefold1 のように名称が変わる。1
  • NonEmptyTraverse: Scalaz では Traverse1。メソッドも nonEmptyTraversetraverse1 となる。
  • Distributive: Traverse の 双対の Distributive はどちらも同様に定義されている。

Apply 〜 Monad

  • Apply: apap2 は同じだが、map2 が Scalaz では apply2 になる。また Cats では InvariantSemigroupal を継承しているが、Scalaz はそうではないという違いがあり、Cats の product(Semigroupal から継承)と、Scalaz の product (Apply[F], Apply[G] から Apply[(F, G)]への合成) では別物になる。
  • Applicative: pure は共通だが、Apply と同様に Cats のみが InvariantMonoidal を継承しており、Cats 版では InvariantMonoidal から継承する point メソッドが、Scalaz では Applicative で初めて宣言される(pure(a)=point(a))。
  • FlatMap: Scalaz では Bind と呼ばれ、メソッド名も flatMapbindflattenjoin と変わる。また地味に大きな違いとして、Cats では FlatMap で宣言されているtailRecM が、Scalaz では別途 BindRec で宣言される。
  • Monad: ほとんど同じ

Semigroupal 〜 ContravariantMonoidal

以下は Cats にのみあって、Scalaz にはない。

  • Semigroupal: (F[A], F[B])=>(F[(A, B)]) となるメソッド productが宣言される。Scalaz の product とは別物(上述)。
  • InvariantSemigroupal: Cats でのみ Apply の基底型クラスとなる(上述)。
  • ContravariantSemigroupal: (特になし)
  • InvariantMonoidal: Cats でのみ Applicative の基底型クラスとなる(上述)。
  • ContravariantMonoidal: (特になし)

SemigroupK 〜 Alternative

  • SemigroupK: Scalaz では Plus と呼ばれる。メソッドも combineKplus になる。ただしエイリアスとなる演算子 <+> は共通。
  • MonoidK: 型名は Scalaz で PlusEmpty となり異なるが、メソッドは empty で同じ。
  • Alternative: Scalaz では ApplicativePlus という型名になる。ソースを見比べると全然ちがうように見えるが、結局 appureemptycombineK/plus を継承する点でだいたい同じになる。
  • IsEmpty: Scalaz のみで、Option のインスタンスなどが提供されている。
  • MonadPlus: Scalaz のみの型クラス。Cats では Alternative で定義されている、separateunite などが、Scalaz ではこちらで定義されている。

Error系

  • ApplicativeError: Cats のみ。Scalaz では MonadErrorで宣言されている raiseErrorhandleError などが、Cats では一階層上のこちらで宣言されている。
  • MonadError: 上述のとおり、Scalaz ではこちらでraiseErrorhandleError などが宣言されている。Cats では Monad(したがって FlatMapも)を継承していることを利用した ensurerethrow と言ったメソッドが定義されている。

CoflatMap 〜 Bimonad

  • CoflatMap: FlatMap/Bind と同様、Scalaz では Cobind というクラス名になり、メソッド名も同様に変わる。
  • Comonad: 型クラス名は共通しているが、extract メソッドが Scalaz では copoint となる。
  • Bimonad: Cats のみ。

その他 Scalaz のみの型クラス

  • Divide: Applycontravariant な型クラスで、apply2 に渡す関数の向きを逆にした divide メソッドが提供される。
  • Divisible: Applicativecontravariant で、pure をひっくり返した conquer が提供される。
  • Align: 「片側一方または両方」となるようなデータの組への操作を提供するもので、\&/ (Cats での Ior) にも関連する。align*、merge、pad* などのメソッドが提供されていて、『FP for Mortals』では Map を題材にした具体例が紹介されている。

ここで触れなかった型クラス

  • 階層を成さない独立した型クラス群: Zip, Unzip, Cozip, Show, Optional など
  • 代数系: Semigroup, Monoid, Band など
  • 比較など: Equal, Order, Enum など
  • モナドトランスフォーマー, Free/FreeT
  • Coyoneda, Lan/Ran などレベル高めの圏論型クラス

追々調べる。

おわりに

  • Cats より記号が多めな気がするが、記号嫌いじゃない派なので好ましい。\/ はよく見るけど、Ior 相当のものが \&/ だったり、オブジェクト指向の文脈でもよくみるリスコフの置換原理が、<~< とか型で表現されてるのも興味深い。
  • 型クラス以外にも便利そうな小物が多い。例えば Memo とか Endo とか、ほぼ同じコードを自前で書いたりしていた。こういうのをいろいろ発見して、また Cats プロジェクトやるときにも知見を活かしたい。
  • 今回は型クラスのみ調べたが、データ型も Cats に無いのが多くて面白そう。
  • 思ったより相違点が多いが、逆に勉強になる。
  1. '1'は「少なくとも一つ」という意味での 1 だろうか?

9
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?