Skip to content

Instantly share code, notes, and snippets.

@fancellu
Last active May 18, 2020 14:08
Show Gist options
  • Save fancellu/3e316f50a107ad627775f309dfd49808 to your computer and use it in GitHub Desktop.
Save fancellu/3e316f50a107ad627775f309dfd49808 to your computer and use it in GitHub Desktop.
Simple Scala higher kinded type example plus type class resolution, pure scala, no Cats
// Higher kinded type example
object HK1 extends App{
// Container C must take a type parameter
trait Maker[C[_]] {
def apply(i: Int): C[Int]
}
implicit object MakerList extends Maker[List] {
def apply(i: Int): List[Int] = List(i)
}
println(MakerList(10))
type EitherString[T] = Either[String, T]
implicit object MakerEitherString extends Maker[EitherString] {
def apply(i: Int): Either[String, Int] = Right(i)
}
// If you use kind projector plugin
// addCompilerPlugin("org.typelevel" %% "kind-projector" % "0.11.0" cross CrossVersion.full)
// object MakerEitherString extends Maker[Either[String, *]] {
// def apply(i: Int): Either[String, Int] = Right(i)
// }
println(MakerEitherString(11))
type Id[T] = T
implicit object MakerId extends Maker[Id] {
def apply(i: Int): Id[Int] = i
}
println(MakerId(12))
// The magic of type classes and implicit resolution
object Maker {
def apply[C[_]](i:Int)(implicit c: Maker[C])= c(i)
}
println(Maker[List](20))
println(Maker[EitherString](21))
println(Maker[Id](22))
}
List(10)
Right(11)
12
List(20)
Right(21)
22
// Higher kinded type example, this time more polymorphic, not just Ints
object HK2 extends App{
// Container C must take a type parameter
trait Maker[C[_], T] {
def apply(i: T): C[T]
}
implicit object MakerList extends Maker[List, Int] {
def apply(i: Int): List[Int] = List(i)
}
println(MakerList(10))
type EitherString[T] = Either[String, T]
implicit object MakerEitherString extends Maker[EitherString, Int] {
def apply(i: Int): Either[String, Int] = Right(i)
}
println(MakerEitherString(11))
type Id[T] = T
implicit object MakerId extends Maker[Id, Int] {
def apply(i: Int): Id[Int] = i
}
println(MakerId(12))
// The magic of type classes and implicit resolution
object Maker {
def apply[C[_],T](i:T)(implicit c: Maker[C, T])= c(i)
}
println(Maker[List, Int](20))
println(Maker[EitherString, Int](21))
println(Maker[Id, Int](22))
implicit object MakerListString extends Maker[List, String] {
def apply(i: String): List[String] = List(i)
}
println(Maker[List, String]("hello"))
implicit object MakerFutureString extends Maker[Future, String] {
def apply(i: String): Future[String] = Future.successful(i)
}
val fut=Maker[Future,String]("hello future")
import scala.concurrent.duration._
val string=Await.result(fut, 3.seconds)
println(string)
}
List(10)
Right(11)
12
List(20)
Right(21)
22
List(hello)
hello future
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment