Partial assessment and currying

I began to understand a few examples related to currying, but I still don't like the concept of currying as I would like. I know that currying can be used for a partial assessment, but I'm not sure how this will work in certain cases.

I know how this works in the following example:

fun funkyPlus xy = x*x+y; 

therefore, suppose we pass only the argument for x, then it is equivalent to the following:

 fun funkyPlus 3 = (fn x => fn y => x*x+y)3 

which ends with a return

 fn y => 9+y 

Now I'm trying to apply this idea to the foldl built-in function.

I know the code for it:

 fun foldl fb [] = b |foldl fb (h::t) = foldl ff(h,b) t. 

My question is if we don’t pass all the arguments to foldl (i.e., pass only the first argument, which is a function ('a*'b->'b) ). In the first example I gave, it was pretty simple to see how a function works when only one of the arguments is passed to it. However, I am having problems with how foldl will work when only one argument is passed.

Reference.

+4
source share
2 answers
  • This does not mean that you think:

     fun funkyPlus 3 = (fn x => fn y => x*x*y)3 

    It defines a function that takes an argument, which must be equal to 3, and which evaluates its RHS if it is equal to 3 and undefined otherwise. You want to say the following: if we provide only an argument for x, we have the following:

     funkyPlus 3 β†’ (fn x => fn y => x*x+y) 3 

    etc.

  • Secondly, there is an error in your foldl :

     fun foldl fb [] = b|foldl fb (h::t) = foldl ff(h,b) t; ^^^^^ Type clash: expression of type 'a * 'b cannot have type 'c list 

    This is because (h,b) parsed as the third argument to foldl , and not as the argument of f . Label it:

     fun foldl fb [] = b|foldl fb (h::t) = foldl f (f(h,b)) t; > val ('a, 'b) foldl = fn : ('a * 'b -> 'b) -> 'b -> 'a list -> 'b 

Now, reaching your question, ML can tell us that an expression of type foldl add will be of type int -> int list -> int .

But overall, this can help to understand that the application of the function is completely mechanical. If we have these two definitions:

 fun foldl fb [] = b | foldl fb (h::t) = foldl f (f(h,b)) t; add (x,y) = x + y; 

then var example = foldl add would be equivalent to this:

 fun example b [] = b | example b (h::t) = example (h::t) (add(h,b)) t; 

All that was done was that add was replaced with f in the body of foldl , no more (although I took the liberty of replacing foldl add with example in the body).

+2
source

The first step is to turn your set of top-level equations for foldl into a lambda expression that uses case analysis, for example:

 val rec foldl = fn f => fn b => fn lst => case lst of [] => b | (h::t) => foldl f (f(h,b)) t 

Now you can use the same logic as before. Taking the function fn (x, y) => x * y as an example, we can see that

 val prod = foldl (fn (x, y) => x * y) 

equivalently

 val prod = (fn f => fn b => fn lst => case lst of [] => b | (h::t) => foldl f (f(h,b)) t) (fn (x, y) => x * y) 

which beta-reduce for

 val prod = fn b => fn lst => case lst of [] => b | (h::t) => foldl (fn (x, y) => x * y) ((fn (x, y) => x * y)(h,b)) t 

which beta comes down to

 val prod = fn b => fn lst => case lst of [] => b | (h::t) => foldl (fn (x, y) => x * y) (h * b) t 

Now, since it is known from our first definition that prod equivalent to foldl (fn (x, y) => x * y) , we can substitute it into our own definition:

 val rec prod = fn b => fn lst => case lst of [] => b | (h::t) => prod (h * b) t 

Then we mentally transform this back into a function defined by equations, if we like:

 fun prod b [] = b | prod b (h::t) = prod (h * b) t 

What about what you expect, right?

+1
source

Source: https://habr.com/ru/post/1339434/


All Articles