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

  1. how put them type checks
  2. what semantics of bind in case of yield

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

Popular posts from this blog

matlab - Deleting rows with specific rules -

php - MySQLi multi_query results for later use -