1

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?

hammar
  • 138,522
  • 17
  • 304
  • 385
esengie
  • 71
  • 4
  • 3
    I'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 Answers1

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