When are lambda forms needed in Haskell?

I am new to Haskell and a relative new to functional programming. In languages ​​other than Haskell, lambda forms are often very useful.

For example, in the diagram:

(define (deriv-approx f) (lambda (hx) (/ (- (f (+ xh) (fx) h))) 

I would create a closure (over function f) to approximate the derivative (with respect to x, with interval h). However, this use of the lambda form does not seem necessary in Haskell due to its partial use:

 deriv-approx fhx = ( (f (x + h)) - (fx) ) / h 

What are some examples where lambda forms are needed in Haskell?

Edit: replace "closure" with "lambda form"

+8
closures haskell scheme higher-order-functions
source share
4 answers

I will give two slightly indirect answers.

First, consider the following code:

 module Lambda where derivApprox fhx = ( (f (x + h)) - (fx) ) / h 

I compiled this by telling the GHC to dump the intermediate view, which is a roughly simplified version of Haskell, used as part of the compilation process to get the following:

 Lambda.derivApprox :: forall a. GHC.Real.Fractional a => (a -> a) -> a -> a -> a [LclIdX] Lambda.derivApprox = \ (@ a) ($dFractional :: GHC.Real.Fractional a) -> let { $dNum :: GHC.Num.Num a [LclId] $dNum = GHC.Real.$p1Fractional @ a $dFractional } in \ (f :: a -> a) (h :: a) (x :: a) -> GHC.Real./ @ a $dFractional (GHC.Num.- @ a $dNum (f (GHC.Num.+ @ a $dNum xh)) (fx)) h 

If you look past dirty annotations and verbosity, you should see that the compiler turned everything into lambda expressions. We can take this as an indication that you probably don't need to do this manually.

Conversely, consider a situation in which you may need lambdas. Here's a function that uses a fold to compile a list of functions:

 composeAll :: [a -> a] -> a -> a composeAll = foldr (.) id 

What is it? Not a lambda in sight! In fact, we can go the other way:

 composeAll' :: [a -> a] -> a -> a composeAll' xs x = foldr (\fgx -> f (gx)) id xs x 

This is not only a full lambdas, but also two arguments for the main function and, moreover, the use of foldr for all of them. Compare the type of foldr , (a -> b -> b) -> b -> [a] -> b with the above; apparently these are three arguments, but above we applied it to four! Not to mention that the battery function takes two arguments, but there are three lambda arguments here. The trick, of course, is that both return a function that takes one argument; and we just apply this argument in place, instead of juggling lambdas around.

All that, I hope, convinced you that these two forms are equivalent. Lambda forms are never needed, or perhaps always necessary, because who can tell the difference?

+12
source share

There is no semantic difference between

 fxyzw = ... 

and

 fxy = \zw -> ... 

The main difference between an expression style (explicit lambdas) and a declaration style is syntactic. One of the situations where this is important is when you want to use the where clause:

 fxy = \zw -> ... where ... -- x and y are in scope, z and w are not 

Indeed, you can write any Haskell program without using an explicit lambda anywhere, replacing them with named local functions or a partial application.

See also: Declaration versus Expression Style .

+6
source share

When you can declare named curry functions (like your Haskell deriv-approx ), you never need to use an explicit lambda expression. Each explicit lambda expression can be replaced by a partial use of a named function that takes free lambda expression variables as first parameters.

Why one would want to do this in the source code is not easy to see, but some implementations, in fact, work just that way.

Also, to some extent, if the next rewriter (other than what I just described) thought that avoid lambda for you?

 deriv-approx f = let myfunc hx = (f(x+h)-(fx))/h in myfunc 
+3
source share

If you use the function only once, for example. as a map or foldr parameter or some other function of a higher order, it is often better to use a lambda than a named function, because it immediately becomes clear that the function is not used anywhere - it cannot be, because it does not have a name . When you introduce a new named function, you give people reading your code one more thing to remember during their validity period. Therefore, lambdas are never strictly necessary, but they are often preferable to alternatives.

0
source share

All Articles