Last active
March 24, 2017 14:37
-
-
Save kubukoz/69257fd31a5ae96b855e3c33d84325e4 to your computer and use it in GitHub Desktop.
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
import cats.instances.list._ | |
import Flatten.Level.Aux | |
import scala.language.higherKinds | |
object Flatten { | |
import cats.Monad | |
import cats.syntax.flatMap._ | |
trait Level { | |
type From[_[_], _] | |
type To[_[_], _] | |
def convert[U, M[_]: Monad](f: From[M, U]): To[M, U] | |
} | |
object Level { | |
type Aux[FFrom[_[_], _], TTo[_[_], _]] = Level { | |
type From[M[_], T] = FFrom[M, T] | |
type To[M[_], T] = TTo[M, T] | |
} | |
} | |
def flatten[L <: Level](implicit levelAux: Level.Aux[L#From, L#To]): Aux[L#From, L#To] = levelAux | |
trait Two extends Level { | |
type From[M[_], T] = M[M[M[T]]] | |
type To[M[_], U] = M[U] | |
override def convert[U, M[_]: Monad](f: M[M[M[U]]]): M[U] = f.flatten.flatten | |
} | |
trait One extends Level { | |
override type From[M[_], T] = M[M[T]] | |
override type To[M[_], T] = M[T] | |
override def convert[U, M[_]: Monad](f: M[M[U]]): M[U] = f.flatten | |
} | |
implicit object Two extends Two | |
implicit object One extends One | |
val ints: List[List[List[Int]]] = List(List(List(5), List(10))) | |
//these types can be inferred automatically | |
val once: List[List[Int]] = flatten[One].convert(ints) | |
val twice: List[Int] = flatten[One].convert(once) | |
val twice3: List[Int] = flatten[Two].convert(ints) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment