Created
January 13, 2020 08:55
-
-
Save ikhoon/a4c6d11ed10fb963eeda208346157bc8 to your computer and use it in GitHub Desktop.
functor expamles
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package category | |
import java.util.concurrent.CompletableFuture | |
object Functors { | |
// Monad 핵심: 많이 쓰인다. | |
// A => B, F[A] => (A => B), => F[B] | |
// Map Pair(A, B) | |
// type class, 특정 타입에 기반된 행위 | |
// "Option", Option[Int], Option[String] | |
// term: F[_] : Higher kind type: 상류 타입 | |
// abstract type | |
// - 불완전한 타입, | |
// - type constructor | |
def toList0(x: Int): List[Int] = List(x) | |
// value level vs. type level | |
def toList[A](x: A): List[A] = List(x) | |
// List[_] => A => List[A] | |
// Type Lambda : TODO | |
// A => Tuple[A, A] | |
type R[A] = (A, A) | |
val x: R[Int] = (10, 10) | |
// List[Int] = * | |
// List = * -> * | |
trait Functor[F[_]] { | |
def map[A, B](fa: F[A])(f: A => B): F[B] | |
} | |
// Working! | |
// Functor | |
// 3개의 법칙 | |
new Functor[Option] { | |
def map[A, B](fa: Option[A])(f: A => B): Option[B] = { | |
fa.map(f) // 1 | |
fa match { // 2 | |
case Some(v) => Some(f(v)) | |
case None => None | |
} | |
} | |
} | |
// 왜 쓰냐? | |
def converter(xs: List[Int]): List[String] = { | |
xs.map(x => (x + 1).toString) | |
} | |
def converter2[A, B](xs: List[A])(f: A => B): List[B] = { | |
xs.map(f) | |
} | |
def converter3[A, B](xs: Option[A])(f: A => B): Option[B] = { | |
xs.map(f) | |
} | |
def fmap[F[_], A, B](xs: F[A])(f: A => B)(functor: Functor[F]): F[B] = { | |
functor.map(xs)(f) | |
} | |
implicit class FunctorSyntax[F[_], A](fa: F[A])(implicit functor: Functor[F]) { | |
def map[B](f: A => B): F[B] = functor.map(fa)(f) | |
} | |
implicit val futureFunctorInstance: Functor[CompletableFuture] = new Functor[CompletableFuture] { | |
def map[A, B](fa: CompletableFuture[A])(f: A => B): CompletableFuture[B] = { | |
val completableFuture = new CompletableFuture[B]() | |
fa.handle((result, cause) => { | |
val b: B = f(result) | |
completableFuture.complete(b) | |
null | |
}) | |
completableFuture | |
} | |
} | |
val completableFuture1 = new CompletableFuture[Int]() | |
// 어떤 타입인지는 상관없다. Functor를 지원하나 안하냐 | |
completableFuture1.map(_ + 1) | |
completableFuture1.complete(10) | |
fmap(completableFuture1)(_ + 1) | |
// CompletableFuture | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment