haskell - How would you make a monad instance of this coroutine? -
i rolling coroutine package education purposes, here is:
data step b r = stop | yield b r | await (a -> r) instance functor (step b) fmap g s = case s of stop -> stop yield b r -> yield b $ g r await f -> await (g . f) data coroutinet m b = cot { resume :: m (step b (coroutinet m b)) } run_ :: monad m => coroutinet m b -> [a] -> m [b] run_ (cot m) = m >>= \step -> case step of stop -> return [] yield o r -> liftm (o:) $ run_ r await k -> case of [] -> return [] (x:xs) -> run_ (k x) xs instance monad m => functor (coroutinet m a) fmap g (cot m) = cot $ liftm ap m ap stop = stop ap (yield b r) = yield (g b) (fmap g r) ap (await k) = await $ (fmap g) . k instance monad m => monad (coroutinet m a) return b = cot . return . yield b $ return b (cot m) >>= g = cot $ liftm go m go stop = stop go (yield b r) = undefined -- * line having trouble go (await k) = await $ (>>=g) . k as see in comments above, line having issue yield case, can see
(>>=) :: coroutinet m b -> (b -> coroutinet m c) -> coroutinet m c (g b) :: coroutinet m c r :: coroutinet m b (r >>= g) :: coroutinet m c but not sure of
- how put them type checks
- what semantics of
bindin case ofyield
the base functor should be:
data step b r x = stop r | yield b x | await (a -> x) ... , coroutine type should be:
data coroutinet m b r = cot { resume :: m (step b r (coroutinet m b r)) } until make 2 fixes won't work.
Comments
Post a Comment