How to make callCC more dynamic?

前端 未结 2 553
忘了有多久
忘了有多久 2020-12-29 05:24

I thought the right type for ContT should be

newtype ContT m a = ContT {runContT :: forall r. (a -> m r) -> m r}

and other control op

2条回答
  •  爱一瞬间的悲伤
    2020-12-29 05:35

    Although there is no way to win the given game, if we can twist the game a little bit we could win!

    newtype ContT' m a =
        ContT' { runContT' :: forall r. (Maybe a -> m (Maybe r)) -> m (Maybe r) }
    

    As we have seen in the other answer, the problem we have is, to win we have to generate a value for an arbitrary type our opponent played, but we do not know how to do so.

    By forcing all raw types (r and a) being decorated by Maybe, we can bypass this problem, and are able to generate a value of any Maybe t -- simply give Nothing to them!

    We got to show this is a Monad.

    instance Monad m => Monad (ContT' m) where
        return a = ContT' $ \k -> k (Just a)
        a >>= f = ContT' $ \c -> runContT' a (
            maybe (return Nothing) (\v -> runContT' (f v) c)) 
    

    And then We can implement callCC:

    class Monad m => MonadCont' m where
        callCC' :: ((a -> forall b.m b) -> m a) -> m a
    
    instance Monad m => MonadCont' (ContT' m) where
        callCC' k = ContT' $ \c -> 
            runContT' (k (\a -> ContT' $ \_ -> c (Just a) >> return Nothing)) c  
    

    I am still working out how to implemen reset and shift.

提交回复
热议问题