可以“继续"吗?后处理其继续的结果 [英] Can a "Cont r a" post-process the result of its continuation

查看:171
本文介绍了可以“继续"吗?后处理其继续的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Cont r a类型代表采用延续a->r并产生类型r的结果的函数.因此,延续和整个Cont r a都产生相同 type r的结果.

the Cont r a type stands for a function which takes a continuation a->r and produces a result of type r. So both the continuation and the entire Cont r a produce a result of the same type r.

我的问题是:两个结果一定是相同的 value ,还是Cont r a可以对延续的结果进行后处理并产生不同的值,尽管类型为?

My question is: are the two results necessarily the same value, or can a Cont r a post-process the result from the continuation and produce a different value, albeit of the same type r?

我尝试使用(+1)进行后期处理(请注意+ 1 --<--):

I tried using (+1) for post-processing (note the + 1 --<--):

c1 :: Int -> Cont r Int
c1 x = let y = 2*x
       in cont $  \k -> (k y)  + 1 --<--

现在不进行类型检查,因为我的后处理函数(+1)仅接受类型属于Num类型类的参数.但是,我传递了延续(k y)的结果,该延续是某种r类型的,不能保证属于Num类型类.

Now that doesn't typecheck, because my post-processing function (+1) only accepts an argument whose type belongs to the Num typeclass. However, I pass the result of the continuation (k y) which is of some type r that is not guaranteed to belong to the Num typeclass.

无论我对(k y)做什么,它都必须是r->r类型的函数.可以对所有r执行此操作的唯一功能是id函数,并且将id用于后处理根本不是后处理.

Whatever I do to (k y), it must be a function of type r->r. The only function which can do this for all r is the id function and using id for post-processing is no post-processing at all.

但是,如果我将r限制为Num类型类,或者甚至将具体类型限制为Int,则整个事情都会进行类型检查.然后产生预期的结果:

However, the whole thing does typecheck if I restrict r to the Num typeclass or even to the concrete type Int. It then produces the expected result:

*Main> runCont (c1 1) id
3

我不太确定,

  • 如果这样的后处理和限制r的类型是正常的事情,如果是的话,在什么情况下这可能有用
  • 或者如果所有r 的类型变量r都必须读为,并且限制r的类型将导致各种麻烦.
  • if such post-processing and restricting the type of r is a normal thing to do, and if so, in what circumstances this might be useful
  • or if the type variable rhas to be read as for all r and restricting the type of r will lead to all sorts of trouble.

有人可以阐明这一点吗?

Can someone shed some light on this?

推荐答案

从技术上讲,我认为很好.从本质上讲,将Cont r a专门化为Num r => Cont r a似乎比将Reader r a专门化为Num r => Reader r a更为麻烦.

Technically, I think it's fine. Specializing Cont r a to Num r => Cont r a doesn't seem fundamentally more problematic than specializing Reader r a to Num r => Reader r a.

这样做的含义是,最终的CPS计算只能针对产生数字的(最终)连续进行,但这很明显-如果您有将连续结果作为数字进行后处理的计算,它只能与产生数字的延续一起使用!

An implication of doing so is that the resulting CPS computation can only be run against a (final) continuation that produces a number, but that's obvious -- if you have a computation that post-processes the continuation result as a number, it can only be used with continuations that produce numbers!

作为至少在某种程度上受到认可的其他证据,请注意有一个功能:

As additional evidence that this is sanctioned at least to some degree, note that there's a function:

mapCont :: (r -> r) -> Cont r a -> Cont r a

如果要不加限制地使用r函数,则它的第一个参数的唯一有效值将是id或不会终止的函数,如您所指出的那样.

If this function was to be used with no restriction on r, the only valid values for its first argument would be id or functions that don't terminate, as you have noted.

使用mapContc1版本可能如下:

c2 :: (Num r) => Int -> Cont r Int
c2 x = mapCont (+1) $ return (2*x)

似乎可以正常工作:

> runCont (c2 10) id
21
> runCont (c2 10) (const 5)
6
> runCont (c2 10) show
... No instance for (Num String) arising from a use of 'c2' ...

至于什么时候该有用 ,我不确定.我可以想到一些有些la脚的应用程序.您可以定义一个覆盖最终结果的计算(前提是不使用其他任何类型的后处理):

As for when this would be useful, I'm not sure. I can think of a few somewhat lame applications. You could define an computation that overrides the final result (provided no other kind of post-processing is used):

override x = cont (const x)

用法如下:

> runCont (return 2 >>= \x -> cont (\f -> f (x*3))) id
6
> runCont (return 2 >> override 1000 >>= \x -> cont (\f -> f (x*3))) id
1000
>

或模仿编写器以添加日志功能的计算转换器:

or a computation transformer that emulates a writer to add log functionality:

annotate note comp = mapCont (\(a, w) -> (a, note:w)) comp

您可能会这样使用:

runCont (annotate "two" (return 2)
        >>= \x -> annotate "times three" (cont (\f -> f (x*3))))
   (\a -> (a, []))

收益:

(6,["two","times three"])

但是,这些应用看起来并不十分引人注目.

These don't seem like very compelling applications, though.

这篇关于可以“继续"吗?后处理其继续的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆