Upgrade to Pro — share decks privately, control downloads, hide ads and more …

自己関手の圏における モノイド対象 in Scala

自己関手の圏における モノイド対象 in Scala

Kazuhiro Ichikawa

March 19, 2022
Tweet

More Decks by Kazuhiro Ichikawa

Other Decks in Programming

Transcript

  1. 型を対象とし、関数の型の関係を考える ´ 右図だと Byte, Int, String が対象 ´ Byte =>

    Int, Int => String, Byte => String が射 ´ 射の合成可能性 = 関数の合成可能性 Int String Byte
  2. 全部 Option 型にしてみる ´ これも圏 ´ 対象: Option[Byte], Option[Int], Option[String]

    ´ 射: Option[Byte] => Option[Int], (略) Option[Int] Option[String] Option[Byte]
  3. ⾼階型 F[_] の表現する圏 ´ 対象: 任意の型 T に対する F[T] ´

    射: 任意の型 T1, T2 に対して F[T1] => F[T2] ´ だいたいこいつを考えておけばOK
  4. Hask圏 ´ 対象: 任意の型 ´ 射: 任意の型 T1, T2 に対して

    T1 => T2 ´ ⾼階型 F[_] の表現する圏の F が Id のバージョンとも考えられる
  5. 我々はこれを知っている ´ Int => String が Option[Int] => Option[String] に対応する

    ´ Option.map: (A => B) => Option[A] => Option[B] Int String Byte Option[Int] Option[String] Option[Byte]
  6. Cats, Scalaz の Functor ´ 射 A => B を

    射 F[A] => F[B] に対応させる ´ Hask圏から⾼階型F[_]の表現する圏への関⼿ trait Functor[F[_]] { def map[A, B](f: A => B): F[A] => F[B] }
  7. Cats, Scalaz の Functor は⾃⼰関⼿ ´ 射 F[A] => F[B]

    は⾃明にHask圏の射でもある trait Functor[F[_]] { def map[A, B](f: A => B): F[A] => F[B] }
  8. 具体例 ´ Option と Future の合成 ´ Option.map: (A =>

    B) => Option[A] => Option[B] ´ Future.map: (A => B) => Future[A] => Future[B] Id Option.map Future.map Future[Option[_]] Option[_]
  9. 具体例 ´ G[_] ⊗ F[_] -> G[F[_]] になる ´ 単位元:

    Id Id Option.map Future.map Future[Option[_]] def compose[A, B](f: A => B): G[F[A]] => G[F[B]] = { Functor[G].map(Functor[F].map(f)) } Option[_]
  10. モノイド対象 ´ モノイド圏の対象Mのうち以下の条件を満たすもの ´ M ⊗ M が M に戻る

    ´ 単位元 を I として I => M の射が存在する ´ イメージとしては、それ⾃⾝がモノイドであるような対象 ´ ⊗ がそれ⾃⾝の⼆項演算になる ´ それ⾃⾝の単位元をモノイド圏全体の単位元から導ける
  11. OptionはFunctorの圏のモノイド対象 ´ Option[_] ⊗ Option[_] = Option[Option[_]] ´ flatten すれば

    Option[_] に戻せる︕ ´ 単位元 Id から Option への射: T => Option[T] ´ これは Some(_) のこと
  12. Functorの圏のモノイド対象 ´ flatten: F[F[A]] => F[A] と unit: A =>

    F[A] があれば良い ´ つまりこうなる trait Monad[F[_]] extends Functor[F[_]] { def flatten[A](f: F[F[A]]): F[A] def unit[A](f: A): F[A] }