由于以下 do 块:

do
  x <- foo
  y <- bar
  return x + y

脱糖为以下形式:
foo >>= (\x -> bar >>= (\y -> return x + y))
\x -> ...y -> ... 实际上不是在这里延续吗?

我想知道是否有办法在 bind 的定义中捕获延续,但我无法正确获取类型。 IE:
data Pause a = Pause a | Stop

instance Monad Pause where
  return x = Stop
  m >>= k = Pause k         -- this doesn't work of course

现在我尝试混淆这些类型:
data Pause a = Pause a (a -> Pause ???) | Stop
                       ------- k ------

但这也行不通。有没有办法捕获这些隐式延续?

顺便说一句,我知道 Cont monad,我只是在试验和尝试一些东西。

最佳答案

好吧,我不太确定,但让我提出一些想法。我不太确定它是什么
应该意味着捕捉延续。例如,您可以捕获整个do 块在一个结构中:

{-# LANGUAGE ExistentialQuantification #-}

import Control.Monad

data MonadExp b = Return b | forall a. Bind (MonadExp a) (a -> MonadExp b)

instance Monad MonadExp where
    return x = Return x
    f >>= g = Bind f g

例如:
block :: MonadExp Int
block = do
    x <- return 1
    y <- return 2
    return $ x + y

instance Show (MonadExp a) where
    show (Return _) = "Return _"
    show (Bind _ _) = "Bind _ _"

print block
>> Bind _ _

然后评估整个事情:
finish :: MonadExp a -> a
finish (Return x) = x
finish (Bind f g) = finish $ g (finish f)

print $ finish block
>> 3

或者逐步通过它并查看零件
step :: MonadExp a -> MonadExp a
step (Return _) = error "At the end"
step (Bind f g) = g $ finish f

print $ step block
>> Bind _ _
print $ step $ step block
>> Return _

好吧,现在我考虑得更多,这可能不是你要问的。但
也许它会帮助你思考。

关于haskell - 有没有办法在 do 符号中捕获延续?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11352346/

10-11 17:17