reset password
Author Message
rabbott
Posts: 1649
Posted 11:49 Oct 02, 2017 |

1. You should be able to talk about each functions individually. Each function should be preceded by comments that explain what it accomplishes. This would be something like the comments you would find with library functions. They don't tell you how the function works but what it computes. 

2. After talking about what a function accomplishes we go on to talk about how it gets that job done. We look at the code and explain how it works. The explanation should be in terms of the functions that are called. But when talking about those functions, talk about what they accomplish for the function in which they are called, not how they do their job. That discussion occurs when we talk about those functions individually.

3. We talk about one function at a time. We move on to talking about another function when we are finished with the current function. At that point there should be no need to come back to that function. Each function stands on its own and should be explained on its own.

4. You should be comfortable with lambda functions. Project 2 includes a number of lambda functions in Part 2. You should understand lambda functions, what they mean, and how they can be used.

For example I can describe an addition function as "A function that takes two arguments, adds them together, and returns the result." That's an English language statement of a function. That statement can be translated into Haskell as (\x y -> x + y). Clearly this is not complex. It illustrates that a lambda function is one with certain arguments and a computation that it performs on those arguments. Note that this function is anonymous. I haven't given it a name. 

Suppose I wanted to give it a name, say "add."  I could write add = (\x y -> x + y). That's exactly the same as writing add x y = x + y. So one way to convert any function into point free notation is drop the parameters and convert it's right hand side into a lambda function in terms of those parameters. Think of going from the add function to add as the name of a lambda function.

I have been asking people to do that. For example, suppose you have the function h = f . g. That's already in point free notation. As most of you know, that's the same as h x = f (g x), which is the same as h = \x -> f (g x). Or we could do this directly h = \x -> (f . g) x

When I have asked people to express h = f . g using a lambda function, after fooling around for a while a number of people have written, h = \x -> f . g $ x. That's also correct. But many people have trouble explaining why it's correct. The answer is that the ($) operator means function application. The function on its left is applied to the arguments on its right.  But before doing the application evaluate what's on the left and right. In this case only x is on the right. So no additional evaluation is required. On the left is f . g. What does it mean to evaluate f . g? It means construct the composition of f and g. What is that composition?

f . g = \y -> f (g y)

So we can substitute that to the left of the $ and get the following h = \x -> (\y -> f (g y) $ x. No more evaluations are required before applying the function to the left of the $ to the argument on the right. In other words, drop the ($) and get h = \x -> (\y -> f (g y) x. The point is that the $ forces the composition of the functions f and g to be performed before applying the result of that composition to x. We would then apply (\y -> f (g y) to x to get f (g x) by substituting x for y. The result of all that is h = \x -> f (g x).

If you have questions about this, please ask.

Last edited by rabbott at 14:27 Oct 02, 2017.