Skip to content

Instantly share code, notes, and snippets.

@MarcelineVQ
Last active October 23, 2019 21:04
Show Gist options
  • Select an option

  • Save MarcelineVQ/61c0bb5e6ea439b7e443298e45a3a1fb to your computer and use it in GitHub Desktop.

Select an option

Save MarcelineVQ/61c0bb5e6ea439b7e443298e45a3a1fb to your computer and use it in GitHub Desktop.
import Control.Applicative
data Coroutine s m r = MkCo { resume :: m (Either (s (Coroutine s m r)) r)}
instance (Functor s, Functor m) => Functor (Coroutine s m) where
fmap f x = MkCo $ fmap (either (Left . fmap (fmap f)) (Right . f)) (resume x)
instance (Functor s, Applicative m) =>
Applicative (Coroutine s m) where
pure = MkCo . pure . Right
f <*> fa = MkCo $ liftA2 fo (resume f) (resume fa)
-- problem part for me
fo :: (Functor s, Applicative m)
=> Either (s (Coroutine s m (a -> b))) (a -> b)
-> Either (s (Coroutine s m a)) a
-> Either (s (Coroutine s m b)) b
fo (Left l) (Left r) = _issue
-- ^ I've got two 's' here, how can I combine them if s isn't Applicative?
-- _issue :: Either (s (Coroutine s m b)) b
-- r :: s (Coroutine s m a)
-- l :: s (Coroutine s m (a -> b))
-- Why can Monad avoid this?
fo (Right l) (Left r) = Left (fmap (fmap l) r)
fo (Left l) (Right r) = Left (fmap (fmap ($ r)) l)
fo (Right l) (Right r) = Right (l r)
instance (Functor s, Monad m) => Monad (Coroutine s m) where
v >>= k = MkCo $ resume v >>= either (pure . Left . fmap (>>= k)) (resume . k)
--
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment