Skip to content

Instantly share code, notes, and snippets.

@AlephAlpha
Created December 18, 2025 07:30
Show Gist options
  • Select an option

  • Save AlephAlpha/f09db131e12216d72de90d676728ba37 to your computer and use it in GitHub Desktop.

Select an option

Save AlephAlpha/f09db131e12216d72de90d676728ba37 to your computer and use it in GitHub Desktop.
Trying to apply the Yoneda Lemma to Kleisli categories.
{-# LANGUAGE RankNTypes #-}
module Yoneda (
Yoneda (..),
liftYoneda,
lowerYoneda,
) where
import Control.Monad.Trans.Class (MonadTrans (..))
newtype Yoneda t m a = Yoneda {runYoneda :: forall r. (a -> m r) -> t m r}
liftYoneda :: (MonadTrans t, Monad m) => t m a -> Yoneda t m a
liftYoneda x = Yoneda $ \k -> x >>= (lift . k)
lowerYoneda :: (Monad m) => Yoneda t m a -> t m a
lowerYoneda y = runYoneda y return
instance Functor (Yoneda t m) where
fmap f m = Yoneda $ \k -> runYoneda m (k . f)
instance (MonadTrans t, Monad m) => Applicative (Yoneda t m) where
pure x = Yoneda $ \k -> lift (k x)
f <*> x = Yoneda $ \k -> runYoneda f return >>= \g -> runYoneda x (k . g)
instance (MonadTrans t, Monad m) => Monad (Yoneda t m) where
x >>= f = Yoneda $ \k -> runYoneda x return >>= \y -> runYoneda (f y) k
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment