Haskell CPS:如何使用Cont monad实现map和filter函数?

时间:2013-05-22 02:49:59

标签: haskell map filter continuation-passing

我一直在努力学习CPS,似乎我并没有真正理解它,你能用Cont monad实现基本过滤器和地图吗?

1 个答案:

答案 0 :(得分:6)

要做到这一点,让我们首先在没有monad的情况下启动,因为CPS不依赖于它。

cpsMap :: (a -> b) -> [a] -> ([b] -> r) -> r
cpsMap f (a:as) c = cpsMap f as (c.(f a:))
cpsMap  _ []    c = c []

map' f xs = cpsMap f xs id

现在Cont monad是微不足道的

contMap :: (a -> b) -> [a] ->  Cont r [b]
contMap f (a:as) = contMap f as >>= return . (f a :)
contMap _ [] = return []

map'' f xs = runCont (contMap f xs) id

这里唯一的区别是我们不必亲自触及延续,return为我们输入值。

要想象它,让我们用map'' (+1) [1..3]

跟踪它
as      | c
[1,2,3] | id
[2,3]   | id . (2 :)
[3]     | id . (2 :) . (3 :)
[]      | id . (2 :) . (3 :) . (4 :)
id . (2 :) . (3 :) . (4 :) $ []
[2, 3, 4]

请注意,所有Cont都会将代码的([b] -> r) -> r部分包装在newtype下。我们真的可以将Cont视为

newtype Cont r a = Cont ((a -> r) -> r)

我会给你实施过滤器:)