(ちょっとずさん) Scala のモナドベースのオプション


今日はしばらくこれに取り組みました.どう思いますか?何を変えますか?
Option のメソッド シグネチャと同じように、型パラメーターを少し「きれいに」することの間には、少しトレードオフがあります.

object Monads extends App {
  trait Functor[+A, F[_]] {
    def map[B](f: A => B): F[B]
  }

  trait Monad[+A, F[_]] extends Functor[A, F] {
    def unit[X](a: => X): F[X]
    def flatMap[B](f: A => F[B]): F[B]
    def map[B](f: A => B): F[B] = flatMap(a => unit(f(a)))
    def flatten[B](implicit ev: A <:< F[B]): F[B] = flatMap[B](identity[A])
  }

  sealed trait Option[+T] extends Monad[T, Option] {
    import Option._
    override def unit[X](a: => X): Option[X] = Some(a)
    override def flatMap[B](f: T => Option[B]): Option[B] = this match {
      case Some(x) => f(x)
      case None => None
    }
  }

  object Option {
    case class Some[T](x: T) extends Option[T]
    case object None extends Option[Nothing]
  }

  import Option._
  val somePinned: Option[Int] = Some(42)
  val nonePinned: Option[Int] = None

  println(somePinned.map(_ * 2))          // Some(42)
  println(nonePinned.map(_ * 2))          // None
  println(Some(Some(42)))                 // Some(Some(42))
  println(Some(Some(42)).flatMap(x => x)) // Some(42)
  println(Some(Some(42)).flatten)         // Some(42)
}


参考文献:
  • https://www.baeldung.com/scala/higher-kinded-types
  • https://medium.com/free-code-camp/demystifying-the-monad-in-scala-cc716bb6f534
  • https://blog.redelastic.com/a-guide-to-scala-collections-exploring-monads-in-scala-collections-ef810ef3aec3
  • https://systemfw.org/posts/flatten.html
  • https://livebook.manning.com/book/functional-programming-in-scala