Skip to content

Instantly share code, notes, and snippets.

@ukitaka
Created February 11, 2017 05:43
Show Gist options
  • Save ukitaka/d357a6664360541222f04020cfce9b25 to your computer and use it in GitHub Desktop.
Save ukitaka/d357a6664360541222f04020cfce9b25 to your computer and use it in GitHub Desktop.
mapを使って実装できるもの
import scala.language.higherKinds
trait InvariantFunctor[F[_]] {
def xmap[A, B](fa: F[A])(f: A => B, g: B => A): F[B]
}
trait Functor[F[_]] extends InvariantFunctor[F] {
def map[A, B](fa: F[A])(f: A => B): F[B]
def xmap[A, B](fa: F[A])(f: A => B, g: B => A): F[B] = map(fa)(f)
def apply[A, B](fa: F[A])(f: A => B): F[B] = map(fa)(f)
def lift[A, B](f: A => B): F[A] => F[B] = fa => map(fa)(f)
def strengthL[A, B](a: A, f: F[B]): F[(A, B)] = map(f)(b => (a, b))
def strengthR[A, B](f: F[A], b: B): F[(A, B)] = map(f)(a => (a, b))
def mapply[A, B](a: A)(f: F[A => B]): F[B] = map(f)(_(a))
def fpair[A](fa: F[A]): F[(A, A)] = map(fa)(a => (a, a))
def fproduct[A, B](fa: F[A])(f: A => B): F[(A, B)] = map(fa)(a => (a, f(a)))
def void[A](fa: F[A]): F[Unit] = map(fa)(_ => ())
}
implicit val optionFunctor = new Functor[Option] {
override def map[A, B](fa: Option[A])(f: (A) => B) = fa match {
case Some(a) => Some(f(a))
case None => None
}
}
optionFunctor.map(Some(123))(_ * 2) // Some(246)
optionFunctor.apply(Some(123))(_ * 2) // Some(246)
optionFunctor.lift((_: Int) + 2).apply(Some(1)) // Some(3)
optionFunctor.strengthL(234, Some(123)) // Some((234, 123))
optionFunctor.strengthR(Some(123), 234) // Some((123, 234))
optionFunctor.mapply(123)(Some((_: Int) * 2)) // Some(246)
// F[A]をF[A => B]に適用できるわけではない
optionFunctor.fpair(Some(1)) // Some(1,1)
optionFunctor.fproduct(Some(1))((_: Int) + 2) // Some(1,3)
optionFunctor.void(Some(123)) // Some(())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment