
Hi, Reading on continuation I've came across this new style of creating the functions which I guess is not very clear in how it works --------------- Prelude> let add_cps x y = \k -> k (x+y) Prelude> add_cps 3 4 $ print 7 --------------- I have some questions as to 1) what is the role of variable 'k' and what eventually happens to it. 2) How does print work after the $ because there is clearly no parameter being passed to it. Thanks, Shishir Srivastava

\k -> k (x + y) is equivalent to blah k = k (x + y) Except for the fact that you have no function name to work with, which is why it is called an anonymous function (or lambda). You can use it anywhere in your code without having to bother create a named function. On Thu, May 28, 2015 at 9:57 AM, Shishir Srivastava < shishir.srivastava@gmail.com> wrote:
Hi,
Reading on continuation I've came across this new style of creating the functions which I guess is not very clear in how it works
--------------- Prelude> let add_cps x y = \k -> k (x+y) Prelude> add_cps 3 4 $ print 7 ---------------
I have some questions as to 1) what is the role of variable 'k' and what eventually happens to it. 2) How does print work after the $ because there is clearly no parameter being passed to it.
Thanks, Shishir Srivastava
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

Hi Shishir, Let's first consider a more straightforward version of the function. λ> let add_cps x y k = k (x+y) So add_cps is a function of x, y, and k, where k is a function that will be applied to x+y. Effectively it converts a function (k) of one argument into a function that takes two arguments. Let's examine the type signature. Now, k could be any function that takes one variable. Why don't we try "print"? In the next example, x=3, y=4, and k=print. What do we expect add_cps to do with those arguments? Well, it should apply the function k (which is "print") to the argument x+y. λ> add_cps 3 4 print 7 And that's what it does! Remember how partial application works? What would happen if we invoke add_cps, but leave out the final argument? The result is a function. That function has no name, and we can't print it, but we can look at its type signature. λ> :t add_cps 3 4 add_cps 3 4 ∷ Num a ⇒ (a → t) → t So this unnamed function takes another function of type a → t, and returns a function of type t. Effectively it converts a function of one argument into a function that takes two arguments. Let's try that with "print". λ> let f = add_cps 3 4 λ> f print 7 This leads us to an equivalent way to write add_cps: λ> let add_cps x y = \k -> k (x+y) This is identical to the first definition, even though it looks very different! Can you see why?

Shishir, You've already gotten some excellent descriptions. As a recovering OO programmer, I get to the same answer by a slightly different path, offered below for what it's worth. When I read the first line: let add_cps x y = \k -> k (x+y) I see a definition of a function (add_cps) with two arguments (x and y) whose evaluation yields a function (\k -> k (x+y)). *I started to write "an anonymous function" out of habit, but stopped myself. I don't think of functions as having names or not having names, any more than I think of expressions as having names or not. Variables are bound to (refer to) values, and a function is just another kind of value to which a variable can refer. (And multiple variables can refer to the same value, by the way, so none of them is really "the name" of the value, regardless of whether that value happens to be a function.)* So at this point, I can think of using the name add_cps in another expression, such as: add_cps 3 4 which (by the substitution principle) must be equivalent to: \k -> k (3+4) That expression is clearly a function (because of the lambda) that takes a single argument and applies it to the expression (3+4) (which isn't yet evaluated, by the way, but when it is I expect it to yield 7). So the argument to that function expression must itself be a function. When I get to the second line: add_cps 3 4 $ print I confess to cheating a bit (and the experts may want to offer me some correction). I mentally rewrite that as: (add_cps 3 4) print because the precedence rules tell me to evaluate the left argument of $ before combining that with what follows. So I can apply the substitution principle to get (\k -> k (3+4)) print and then apply it again to get print (3+4) Hope this helps, -jn- On Thu, May 28, 2015 at 8:57 AM, Shishir Srivastava < shishir.srivastava@gmail.com> wrote:
Hi,
Reading on continuation I've came across this new style of creating the functions which I guess is not very clear in how it works
--------------- Prelude> let add_cps x y = \k -> k (x+y) Prelude> add_cps 3 4 $ print 7 ---------------
I have some questions as to 1) what is the role of variable 'k' and what eventually happens to it. 2) How does print work after the $ because there is clearly no parameter being passed to it.
Thanks, Shishir Srivastava
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- Beauty of style and harmony and grace and good rhythm depend on simplicity. - Plato
participants (4)
-
Amy de Buitléir
-
David McBride
-
Joel Neely
-
Shishir Srivastava