writeChan :: forall t a . (SunroofThread t, SunroofArgument a) => a -> JSChan a -> JS t ()
writeChan a (match -> (written,waiting)) = do
  ifB ((waiting ! length') ==* 0)
      (do f <- continuation $ \ (k :: JSContinuation a) -> goto k a :: JSB ()
          _ <- written # push (f :: JSContinuation (JSContinuation a))
          return ()
      )
      (do f <- shift waiting
          forkJS (goto f a :: JSB ())
      )

-- | Take a value out of the channel. If there is no value
--   inside, this will block until one is available.
writeChan :: forall t a . (SunroofThread t, SunroofArgument a) => a -> JSChan a -> JS t ()
writeChan a (match -> (written,waiting)) = do
  ifB ((waiting ! length') ==* 0)
      (do f <- continuation $ \ (k :: JSContinuation a) -> goto k a :: JSB ()
          _ <- written # push (f :: JSContinuation (JSContinuation a))
          return ()
      )
      (do f <- shift waiting
          forkJS (goto f a :: JSB ())
      )

-- | Take a value out of the channel. If there is no value
--   inside, this will block until one is available.
writeChan a (match -> (written,waiting)) = do
  ifB ((waiting ! length') ==* 0)
      (do f <- continuation $ \ (k :: JSContinuation a) -> goto k a :: JSB ()
          _ <- written # push (f :: JSContinuation (JSContinuation a))
          return ()
      )
      (do f <- shift waiting
          forkJS (goto f a :: JSB ())
      )

-- | Take a value out of the channel. If there is no value
--   inside, this will block until one is available.