回文和丹维对直接风格的评论

nic*_*las 6 recursion continuations haskell callcc continuation-passing

这是一些代码,以“直接样式”确定列表在 n+1 比较中是否为回文

pal_d1 :: Eq a => [a] -> Bool
pal_d1 l = let (r,_) = walk l l in r
        where walk l           [] = (True,l) 
              walk l       (_:[]) = (True,tail l)
              walk (x:l) (_:_:xs) = let (r, y:ys) = walk l xs
                                    in (r && x == y, ys)      
Run Code Online (Sandbox Code Playgroud)

可以在几个例子上进行测试

-- >>> pal_d1 [1,2,1]
-- True

-- >>> pal_d1 [1,2,2,1]
-- True

-- >>> pal_d1 [1,2,3,4,2,1]
-- False
Run Code Online (Sandbox Code Playgroud)

Danvy 在“ There and back again ”中声称没有控制运算符(就在 4.2 之前)没有直接的风格解决方案,因为在下面的 CPS 风格解决方案中非线性使用了延续:

pal_d1 :: Eq a => [a] -> Bool
pal_d1 l = let (r,_) = walk l l in r
        where walk l           [] = (True,l) 
              walk l       (_:[]) = (True,tail l)
              walk (x:l) (_:_:xs) = let (r, y:ys) = walk l xs
                                    in (r && x == y, ys)      
Run Code Online (Sandbox Code Playgroud)

第一个代码如何不与此断言相矛盾?

(以及如何不线性使用延续?)

Li-*_*Xia 4

他并没有声称没有控制操作符就没有解决方案。

延续不是线性使用的,因此将该程序映射回直接样式需要一个控制运算符。

这篇论文的背景是研究直接风格和 CPS 之间的系统转换,该段落的主张是,如果延续以奇特的方式使用,从 CPS 返回是很棘手的。

经过一些努力,您可以将其恢复为良好的形状,但问题仍然存在,编译器如何自动执行此操作?

(以及如何不线性使用延续?)

在本文中,延续位于andalso( &&) 的右侧,因此如果左侧操作数为 ,则它会被丢弃False

在操作语义中,您可以将延续视为评估上下文,并且在该视图中丢弃延续对应于引发异常。人们当然可以做到这一点,但关键是这需要源语言中的额外机制。