Haskell 使用MonadRef实现MonadContent

Haskell 使用MonadRef实现MonadContent,haskell,continuations,delimited-continuations,Haskell,Continuations,Delimited Continuations,有一个众所周知的问题 但是,可以使用以下定义: class Monad m => MonadCont' m where callCC' :: ((a -> forall b. m b) -> m a) -> m a shift :: (forall r.(a -> m r) -> m r) -> m a reset :: m a -> m a 然后找到一个有意义的例子。在本文中,作者声称我们可以在conttrm的基础上实现

有一个众所周知的问题

但是,可以使用以下定义:

class Monad m => MonadCont' m where
    callCC' :: ((a -> forall b. m b) -> m a) -> m a
    shift :: (forall r.(a -> m r) -> m r) -> m a
    reset :: m a -> m a
然后找到一个有意义的例子。在本文中,作者声称我们可以在
conttrm
的基础上实现
MonadFix
,前提是
m
实现
MonadFix
MonadRef
。但是我认为如果我们有一个
MonadRef
,我们实际上可以实现上面的
callCC'
,如下所示:

--satisfy law: mzero >>= f === mzero
class Monad m => MonadZero m where
    mzero :: m a

instance (MonadZero m, MonadRef r m) => MonadCont' m where
    callCC' k = do
        ref <- newRef Nothing
        v <- k (\a -> writeRef ref (Just a) >> mzero)
        r <- readRef ref
        return $ maybe v id r
    shift = ...
    reset = ...
我们必须调整实施以适应环境

instance (MonadPlus m, MonadRef r m) => MonadCont' m where
    callCC' k = do 
       ref <- newRef mzero
       mplus (k $ \a -> writeRef ref (return a) >> mzero) (join (readRef ref))
instance(MonadPlus m,MonadRef r m)=>MonadCont'm其中
callCC'k=do
ref writeRef ref(返回a)>>mzero(连接(readRef ref))
换句话说,原始的
MonadZero
是不够的,我们必须能够将
mzero
值与正常计算相结合,而不取消整个计算

以上没有回答问题,只是因为最初的尝试被伪造为候选人而进行了调整。但对于更新版本,原始问题仍然是问题。特别是,
reset
shift
仍有待实施。

(这还不是答案,但我脑子里只想到了一些线索。我希望这能让我自己或其他人得到真正的答案。)

--菲利普·瓦德勒

在上面的文章中,作者介绍了“对偶演算”,一种与经典逻辑相对应的类型演算。在最后一节中,有一段说

一种按需打电话的双重策略可以 通过用协项的值覆盖协项来避免这种低效 第一次评估时

正如Wadler的论文中所述,按名称调用急切地评估连续性(它在评估所有值之前返回),而按值调用缓慢地评估连续性(它只在评估所有值之后返回)

现在,看一看上面的
callCC'
,我相信这是延续端中按需调用的双重示例。求值的策略是为给定的函数提供一个假“延续”,但在此时缓存状态,以便稍后调用“真”延续。这在某种程度上类似于对延续进行缓存,因此一旦计算完成,我们将恢复该延续。但是缓存评估值是指按需调用


一般来说,我怀疑状态(计算到当前时间点)与延续(未来计算)是对偶的。这将解释一些现象。如果这是真的,那么
MonadRef
(对应于全局和多态状态)与
MoncadCont
(对应于全局和多态连续状态)是双重的就不足为奇了,因此它们可以相互实现。

您的更新是否等于对您的问题的回答?如果是这样的话,也许你可以把它贴出来,这样这个问题就不再被认为是没有答案的了?
instance (MonadPlus m, MonadRef r m) => MonadCont' m where
    callCC' k = do 
       ref <- newRef mzero
       mplus (k $ \a -> writeRef ref (return a) >> mzero) (join (readRef ref))