문제

I've been trying to learn CPS, seems I didn't really get my head around it, could you implement basic filter and map using Cont monad?

도움이 되었습니까?

해결책

To do this, let's first start without the monad since CPS isn't dependent on it.

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

And now the Cont monad is trivial

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

The only difference here is we don't have to touch the continuations ourselves, return pipes the value into it for us.

To visualize it let's trace it with 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]

Notice that all Cont does is wrap the ([b] -> r) -> r part of our code under a newtype. Really we can think of Cont as

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

I'll leave implementing filter to you :)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top