Skip to content

Instantly share code, notes, and snippets.

@chenharryhua
Created March 27, 2018 09:28
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 chenharryhua/0140ba492554fd81540082fb4b95579a to your computer and use it in GitHub Desktop.
Save chenharryhua/0140ba492554fd81540082fb4b95579a to your computer and use it in GitHub Desktop.
package essence.iterator.pattern
import cats._, cats.data._, cats.implicits._
object ThePaper {
//(⊗)::(Functor m,Functor n) ⇒ (a → m b) → (a → n b) → (a → (m*n) b)
def ⊗[M[_]: Functor, N[_]: Functor, A, B](f: A => M[B])(g: A => N[B])(a: A): Tuple2K[M, N, B] = Tuple2K(f(a), g(a))
//(⊙)::(Functor n,Functor m) ⇒ (b → n c) → (a → m b) → (a → (m . n) c)
def ⊙[M[_]: Functor, N[_]: Functor, A, B, C](f: A => M[B])(g: B => N[C])(a: A): M[N[C]] = f(a).map(g)
//collect ::(Traversable t,Applicative m) ⇒ (a → m ()) → (a → b) → t a → m (t b)
def collect[T[_], M[_], A, B](f: A => M[Unit], g: A => B, ta: T[A])(
implicit
M: Applicative[M], T: Traverse[T]): M[T[B]] =
T.traverse[M, A, B](ta)(a => M.ap[Unit, B](M.pure(Unit => g(a)))(f(a)))(M)
//disperse ::(Traversable t,Applicative m) ⇒ m b → (a → b → c) → t a → m (t c)
def disperse[T[_]: Traverse, M[_]: Applicative, A, B, C](
mb: M[B],
g: A => B => C,
ta: T[A]): M[T[C]] = ta.traverse(a => mb.map(g(a)))
//newtype Backwards m a = Backwards{runBackwards::m a}
final case class Backwards[M[_], A](runBackwards: M[A])
//instance Applicative m ⇒ Applicative (Backwards m)
implicit def backwardsApplicative[M[_]](implicit M: Applicative[M]) =
new Applicative[Backwards[M, ?]] {
def pure[A](a: A) = Backwards(M.pure(a))
def ap[A, B](ff: Backwards[M, A => B])(fa: Backwards[M, A]): Backwards[M, B] =
Backwards(M.ap(ff.runBackwards)(fa.runBackwards))
}
//data AppAdapter m where
//AppAdapter::Applicative (g m) ⇒
//(∀a. m a → g m a) → (∀a. g m a → m a) → AppAdapter m
trait AppAdapter[G[_[_], _], M[_]] {
def insert[A]: M[A] => G[M, A]
def retrieve[A]: G[M, A] => M[A]
}
trait AppAdapter2[M[_]] {
def insert[G[_[_], _], A]: M[A] => G[M, A]
def retrieve[G[_[_], _], A]: G[M, A] => M[A]
}
//backwards::Applicative m ⇒ AppAdapter m
//backwards = AppAdapter Backwards runBackwards
def backwards[M[_]]: AppAdapter[Backwards, M] =
new AppAdapter[Backwards, M] {
def insert[A] = (ma: M[A]) => Backwards(ma)
def retrieve[A] = (bw: Backwards[M, A]) => bw.runBackwards
}
//ptraverse ::(Applicative m,Traversable t) ⇒
//AppAdapter m → (a → m b) → t a → m (t b)
//ptraverse (AppAdapter insert retrieve) f = retrieve ◦ traverse (insert ◦ f)
def ptraverse[M[_]: Applicative, T[_]: Traverse, A, B](
aa: AppAdapter[Backwards, M],
f: A => M[B],
ta: T[A]): M[T[B]] = aa.retrieve(ta.traverse(a => aa.insert(f(a))))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment