Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 有没有一种方法可以捕捉do符号中的连续体?_Haskell_Types_Continuations_Coroutine_Continuation Passing - Fatal编程技术网

Haskell 有没有一种方法可以捕捉do符号中的连续体?

Haskell 有没有一种方法可以捕捉do符号中的连续体?,haskell,types,continuations,coroutine,continuation-passing,Haskell,Types,Continuations,Coroutine,Continuation Passing,由于以下原因,请执行以下操作: do x <- foo y <- bar return x + y \x->…和y->…实际上不是在这里继续吗 我想知道是否有一种方法可以捕获bind定义中的continuations,但我无法获得正确的类型。即: data Pause a = Pause a | Stop instance Monad Pause where return x = Stop m >>= k = Pause k --

由于以下原因,请执行以下操作:

do
  x <- foo
  y <- bar
  return x + y
\x->…
y->…
实际上不是在这里继续吗

我想知道是否有一种方法可以捕获
bind
定义中的continuations,但我无法获得正确的类型。即:

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 ------
但这也不行。没有办法捕捉这些隐含的延续吗


顺便说一句,我知道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 _ _
或者一步一步地穿过它,看看它的各个部分

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 _
好吧,现在我想得更多了,这可能不是你要问的。但是
也许这会帮助你思考。

嗯,我不知道你的lambda是否是这个术语最严格意义上的延续,但在我看来,它们也与这个概念相似

但是请注意,如果它们是连续的,那么被删除的一元代码已经是以连续传递样式(CPS)编写的。“捕获”延续的控制运算符的通常概念是基于直接样式的程序;“捕获的”延续仅在直接样式程序中是隐式的,但CPS转换使其显式

由于被删除的一元代码已经存在于CPS或类似的东西中,那么,一元代码是否能够表达CPS代码所能表达的一些控制流技巧,也许是一种解决问题的方法。通常,这些技巧可以归结为这样一种想法:在CPS机制下,函数通过调用其延续来完成是一种惯例,而函数可以选择用它选择的另一个延续来替换它的延续。此替换延续可以参照原始延续进行构造,这样,如果选择,它可以依次“恢复”原始延续。例如,协程被实现为一个相互的“替换/恢复”循环

从这个角度来看,我认为你的答案大多是否定的;CPS要求在
foo>=bar
中,
foo
必须能够选择是否调用
bar
,并且
foo
必须是缩写,以提供
bar
的替代品,但是
(>=)
本身并没有提供
foo
执行此操作的机制,更重要的是,
(>=)
控制执行流,而不是
foo
。一些特定的monad实现了它的部分或全部(例如,
可能
monad允许
foo
通过生成
结果来放弃执行
),但其他monad则不这样做

我能得到的最接近的方法是放弃
(>>=)
,改用这个:

-- | Execute action @foo@ with its "continuation" @bar@.
callCC :: Monad m => ((a -> m b) -> m b) -> (a -> m b) -> m b
foo `callCC` bar = foo bar

这里
foo
可以选择是否使用
bar
。但是请注意,这个
callCC
实际上只是
($)

我不确定,但也许你需要更仔细地思考你所说的“捕捉延续”是什么意思。看看你对
>=
的定义:它扔掉了第一个参数。。。那么第一个论点在那里做什么呢?这正是我想要做的——存在类型是缺失的环节。谢谢
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 _
-- | Execute action @foo@ with its "continuation" @bar@.
callCC :: Monad m => ((a -> m b) -> m b) -> (a -> m b) -> m b
foo `callCC` bar = foo bar