ekmett / kan-extensions

Kan extensions, Kan lifts, the Yoneda lemma, and (co)monads generated by a functor
Other
78 stars 33 forks source link

Add oneShot to Codensity instances #78

Open Icelandjack opened 6 months ago

Icelandjack commented 6 months ago

The IOSim s Monad has the same instances as Codensity (SimA s) except with oneShot. Could be added to the Codensity instances, giving the compiler better hints and allowing the io-sim library to derive via Codensity.


newtype IOSim s a = IOSim { unIOSim :: forall r. (a -> SimA s r) -> SimA s r }

instance Functor (IOSim s) where
    {-# INLINE fmap #-}
    fmap f = \d -> IOSim $ oneShot $ \k -> unIOSim d (k . f)

instance Applicative (IOSim s) where
    {-# INLINE pure #-}
    {-# INLINE (<*>) #-}
    {-# INLINE (*>) #-}
    pure = \x -> IOSim $ oneShot $ \k -> k x
    (<*>) = \df dx -> IOSim $ oneShot $ \k -> unIOSim df (\f -> unIOSim dx (\x -> k (f x)))
    (*>) = \dm dn -> IOSim $ oneShot $ \k -> unIOSim dm (\_ -> unIOSim dn k)

instance Monad (IOSim s) where
    {-# INLINE (>>=) #-}
    {-# INLINE (>>) #-}
    return = pure
    (>>=) = \dm f -> IOSim $ oneShot $ \k -> unIOSim dm (\m -> unIOSim (f m) k)
    (>>) = (*>)
RyanGlScott commented 6 months ago

I'm in favor. GHC includes a vendored-in copy of Codensity here, which provides an example of how to define its instances using oneShot.