Search code examples
haskellcontinuations

Haskell, Simple Continuation


I am having hard time to convert a simple CPS function

This is a CPS style square function

-- from : http://en.wikibooks.org/wiki/Haskell/Continuation_passing_style
square :: Int -> Int
square x = x * x

square_cps :: Int -> ((Int -> r) -> r)
square_cps = \cont -> cont (square x)
-- square_cps 3 print will write '9' out in console

Now, I would like to change the function arguments in reverse order

square_cps' :: ((Int -> r) -> r) -> Int
square_cps' = ?

Is it impossible?


Solution

  • First a minor correction to your definition of square_cps:

    square_cps :: Int -> ((Int -> r) -> r)
    square_cps x = \cont -> cont (square x)
              ^^^
    

    Alternatively you can write:

    square_cps x cont = cont (square x)
    

    Note that this works even though the type signature makes square_cps look like a function of only one argument.

    Now, the type signature for square_cps' can't work. They way it is written it means that you could get an Int out of a (Int -> r) -> r which is a function which returns an r.

    To flip the arguments to square_cps, first write this equivalent type signature:

    square_cps :: Int -> (Int -> r) -> r
                  ^      ^             ^--- result
                  |       \--- second arg
                  \--- first arg
    

    and identify the arguments as shown. Then swapping the first and second arguments results in this signature:

    square_cps' :: (Int -> r) -> Int -> r
    square_cps' cont x = square_cps x cont
    

    In general, the signature a -> b -> c is equivalent to a -> (b -> c), i.e. the function type constructor associates to the right.