Skip to content

Instantly share code, notes, and snippets.

@debasishg
Last active September 28, 2021 13: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 debasishg/75245471dab5666727c6ce49551df83f to your computer and use it in GitHub Desktop.
Save debasishg/75245471dab5666727c6ce49551df83f to your computer and use it in GitHub Desktop.
Encoding for Cayley transform in Scala
import cats.{ Applicative, Functor }
import cats.syntax.all._
/** Is this the proper Scala encoding for the Haskell snippet in comments ? */
/** from : https://doisinkidney.com/pdfs/algebras-for-weighted-search.pdf */
// newtype Cayley f a = Cayley {runC :: ∀b. f b → f (a, b) }
sealed trait Cayley[F[_], A] {
def apply[B](fb: F[B]): F[(A, B)]
}
/** Now I define the laws of isomorphism for Cayley transforms */
// abs :: Applicative f ⇒ f a → Cayley f a
// abs x = Cayley (liftA2 (, ) x)
def abs[F[_]: Applicative, A](fa: F[A]): Cayley[F, A] =
new Cayley[F, A] {
def apply[B](fb: F[B]): F[(A, B)] =
liftA2(fa, fb)((a: A) => (b: B) => (a, b))
}
// rep :: Applicative f ⇒ Cayley f a → f a
// rep x = fmap fst (runC x (pure ()))
def rep[F[_]: Applicative, A](cfa: Cayley[F, A]): F[A] =
cfa.apply(().pure[F]).map(_._1)
/**
* Now I am trying to define an Applicative instance for Cayley[F, A]
* and facing problems with type unification of existentials. The problem is in
* defining the `ap` method of the applicative. How does type unification work
* with existentials in Scala ?
*/
// instance Functor f ⇒ Applicative (Cayley f ) where
// pure x = Cayley (fmap (x, ))
// fs <*> xs = Cayley (fmap (𝜆(f , (x, xs)) → (f x, xs)) ◦ runC fs ◦ runC xs)
def cayleyApplicative[F[_]: Functor] = new Applicative[Cayley[F, *]] {
def pure[A](a: A) = new Cayley[F, A] {
def apply[B](fb: F[B]): F[(A, B)] =
fb.map((b: B) => (a, b))
}
def ap[A, B](fs: Cayley[F, A => B])(xs: Cayley[F, A]): Cayley[F, B] = ???
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment