Skip to content

Instantly share code, notes, and snippets.

@akirillov
Last active July 21, 2016 21:33
Show Gist options
  • Save akirillov/a9bd3df0e90294adb299b4062801e3d8 to your computer and use it in GitHub Desktop.
Save akirillov/a9bd3df0e90294adb299b4062801e3d8 to your computer and use it in GitHub Desktop.
/*
for the test purposes function getValueAsync imitates some heavy lifting
and returns type constructor parametrized by T (same for getValueOpt)
in real life these could be different functions returning some type
constructors like Option, List and Future which values
should then be passed to a function which takes proper types
Apply type class from cats has methods with a flavor like that:
def ap[A, B](f: F[A => B])(fa: F[A]): F[B]
where f is a function in the context of F (Option, List etc)
so for Option it will look like this:
def ap[A, B](f: Option[A => B])(fa: Option[A]): Option[B] =
fa.flatMap(a => f.map(ff => ff(a)))
Let's check how Apply can be used for the given use case
*/
def getValueAsync[T](sleep: Long, value: T): Future[T] = Future {
Thread.sleep(sleep)
value
}
//example function for Option
def getValueOpt[T](value: T): Option[T] = Some(value)
//function accepts two proper types (without wrappers/containers)
val f = (x: String, y: Int) => x + " " + y
//here, function f is lifted into Future context, so it could be applied to values inside
//Future and result in the new Future
val result = Apply[Future].map2(getValueAsync(1000, "hello"), getValueAsync(2000, 42))(f)
//OR
val result2 = getValueAsync(1000, "hello") |@| getValueAsync(2000, 42) map f
Await.result(result, 3 seconds) //hello 42
Await.result(result2, 3 seconds) //hello 42
//Option example
getValueOpt("hello") |@| getValueOpt(42) map f //Some("hello 42")
None |@| getValueOpt(42) map f //None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment