Skip to content

Instantly share code, notes, and snippets.

@nafg
Created July 8, 2012 04:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nafg/3069314 to your computer and use it in GitHub Desktop.
Save nafg/3069314 to your computer and use it in GitHub Desktop.
Map and WIP foldLeft for Pairs
trait ~>[F[_], G[_]] {
def apply[T](f: F[T]): G[T]
}
// object ~> {
// class From[F[_]] { type To[G[_]] = ~>[From, To] }
// }
trait Const[C] {
type T[X] = C
}
case class CanMapPair[-P1, F[_], G[_], P2](m: P1 => (F ~> G) => P2)
object CanMapPair {
implicit def single[A, F[_], G[_]] = CanMapPair[F[A], F, G, G[A]](fa => f => f(fa))
implicit def pair[A1, B1, F[_], G[_], A2](implicit cmp: CanMapPair[A1, F, G, A2]) = CanMapPair[(A1, F[B1]), F, G, (A2, G[B1])](
{ case (a1, fb1) => f => (cmp.m(a1)(f), f(fb1)) }
)
}
case class MappablePair[P1](p: P1) {
def map[F[_], G[_], P2](f: F ~> G)(implicit cmp: CanMapPair[P1, F, G, P2]): P2 = cmp.m(p)(f)
}
implicit def pairToMappable[P1](p: P1): MappablePair[P1] = MappablePair(p)
/**
* ((List(1),List(2)),List(3)).foldLeft(0::Nil)(_ ::: _) = // CanFoldPair[((List[Int],List[Int]),List[Int]), List[Int], List, List, List, List[Int]]
* (List(2), List(3)).foldLeft(0::1::Nil)(_ ::: _) =
* List(3).foldLeft(0::1::2::Nil)(_ ::: _) = // CanFoldPair[List[Int], List[Int], List, List, List, List[Int]]
* (("0" + 1) + 2) + 3
* @tparam P1 The type of the left side of foldLeft ("this")
* @tparam Z The type of the "seed" of the foldLeft
* @tparam F1 The first argument kind of the folding function
* @tparam F2 The second argument kind of the folding function
* @tparam G The return kind of the folding function
* @tparam P2 The return type of foldLeft
*/
case class CanFoldPair[-P1, Z, F1[_], F2[_], G[_], P2](m: Z => P1 => (F1 ~> Const[F2 ~> G]#T) => P2)
object CanFoldPair {
implicit def single[A, Z, F1[_], F2[_], G[_]] = CanFoldPair[F1[Z], F2[A], F1,F2,G,G[A]](z => f1a => f => f(f1a)(z))
implicit def pair[A1,B1,Z,F1[_],F2[_],G[_], A2](implicit cfp: CanFoldPair[A1,Z,F1,F2,G,A2]) =
CanFoldPair((z: Z) => (in: (A1, F1[B1])) => (f: F1~>Const[F2~>G]#T) => cfp.m(z)(in._1))
}
case class FoldablePair[P1](p: P1) {
def foldLeft[F1[_],F2[_], G[_], P2,Z](z: Z)(f: F1 ~> Const[F2~>G]#T)(implicit cfp: CanFoldPair[P1, Z,F1,F2, G, P2]): P2 = cfp.m(z)(p)(f)
}
implicit def pairToFoldable[P1](p: P1): FoldablePair[P1] = FoldablePair(p)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment