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?
Asked
Active
Viewed 1,231 times
1
-
3I'm not really sure what you're asking. I think a good first step would be to ignore the Cont monad itself and just write some code in CPS using continuations explicitly. – Tikhon Jelvis May 22 '13 at 03:14
-
There are some good papers here that might be useful: http://www.cs.indiana.edu/~dfried/ – Wes May 22 '13 at 04:37
1 Answers
6
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 :)

Vitus
- 11,822
- 7
- 37
- 64

daniel gratzer
- 52,833
- 11
- 94
- 134
-
No problem, if this answers your question, please tick the green check box to mark the question as answered – daniel gratzer May 22 '13 at 06:48
-
1The `cpsMap` function uses CPS style for the map function itself, but not for calling `f`. If you really want CPS you need to change the type of `f` as well. – augustss May 22 '13 at 08:17
-
-
3I do not find it particularly helpful that you arbitrarily restrict the result type of `cpsMap` and `contMap` to `[b]`. – kosmikus May 22 '13 at 10:15
-
@kosmikus Fair enough, I thought that it would make it a bit clearer that it was a `map`, I've edited it though – daniel gratzer May 22 '13 at 13:34