scalaz.Cojoin.scala Maven / Gradle / Ivy
The newest version!
package scalaz
trait Cojoin[M[_]] {
def cojoin[A](a: M[A]): M[M[A]]
}
object Cojoin {
import Scalaz._
implicit def IdentityCojoin: Cojoin[Identity] = new Cojoin[Identity] {
def cojoin[A](a: Identity[A]) = a
}
implicit def NonEmptyListCojoin: Cojoin[NonEmptyList] = new Cojoin[NonEmptyList] {
def cojoin[A](a: NonEmptyList[A]) = a.tails
}
implicit def Tuple1Cojoin: Cojoin[Tuple1] = new Cojoin[Tuple1] {
def cojoin[A](a: Tuple1[A]) = Tuple1(a)
}
implicit def Tuple2Cojoin[R]: Cojoin[({type λ[α]=(R, α)})#λ] = new Cojoin[({type λ[α]=(R, α)})#λ] {
def cojoin[A](a: (R, A)) = (a._1, a)
}
implicit def Function0Cojoin: Cojoin[Function0] = new Cojoin[Function0] {
def cojoin[A](a: () => A) = () => a
}
import java.util.concurrent.Callable
implicit def CallableCojoin: Cojoin[Callable] = new Cojoin[Callable] {
def cojoin[A](a: Callable[A]) = new Callable[Callable[A]] {
def call = a
}
}
import java.util.Map.Entry
import java.util.AbstractMap.SimpleImmutableEntry
implicit def MapEntryCojoin[X]: Cojoin[({type λ[α]=Entry[X, α]})#λ] = new Cojoin[({type λ[α]=Entry[X, α]})#λ] {
def cojoin[A](a: Entry[X, A]) = new SimpleImmutableEntry(a.getKey, a)
}
implicit def ZipperCojoin: Cojoin[Zipper] = new Cojoin[Zipper] {
def cojoin[A](a: Zipper[A]) = a.positions
}
implicit def TreeCojoin: Cojoin[Tree] = new Cojoin[Tree] {
def cojoin[A](a: Tree[A]): Tree[Tree[A]] = a.cobind(identity(_))
}
implicit def TreeLocCojoin: Cojoin[TreeLoc] = new Cojoin[TreeLoc] {
def cojoin[A](a: TreeLoc[A]): TreeLoc[TreeLoc[A]] = {
val lft = (_: TreeLoc[A]).left
val rgt = (_: TreeLoc[A]).right
val p = a.parent.unfold[Stream, (Stream[Tree[TreeLoc[A]]], TreeLoc[A], Stream[Tree[TreeLoc[A]]])]((o: Option[TreeLoc[A]]) =>
for (z <- o) yield ((uf(z, lft), z, uf(z, rgt)), z.parent))
loc(a.unfoldTree(dwn[A](_: TreeLoc[A])), uf(a, lft), uf(a, rgt), p)
}
private def uf[A](a: TreeLoc[A], f: TreeLoc[A] => Option[TreeLoc[A]]): Stream[Tree[TreeLoc[A]]] =
f(a).unfold[Stream, Tree[TreeLoc[A]]]((o: Option[TreeLoc[A]]) =>
for (c <- o) yield (c.unfoldTree(dwn[A](_: TreeLoc[A])), f(c)))
private def dwn[A](tz: TreeLoc[A]): (TreeLoc[A], () => Stream[TreeLoc[A]]) =
(tz, () => tz.firstChild.unfold[Stream, TreeLoc[A]]((o: Option[TreeLoc[A]]) =>
for (c <- o) yield (c, c.right)))
}
import concurrent.Promise
implicit def PromiseCojoin: Cojoin[Promise] = new Cojoin[Promise] {
def cojoin[A](a: Promise[A]) = promise(a)(a.strategy)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy