7

I'm supposed to take this code:

f x y z = x^3 - g (x + g (y - g z) + g (z^2))
 where g x = 2*x^2 + 10*x + 1

And rewrite it without where (or let).

They mean to write it with a Lambda function (\x ->...)

I'm trying to reuse a Lambda function on Haskell. Any ideas?

1
  • 6
    f = flip flip ((1 +) . ap ((+) . (2 *) . (^ 2)) (10 *)) . (flip .) . ap ((.) . (.) . (.) . (-) . (^ 3)) (((ap id .) .) . flip flip (flip id . (^ 2)) . (liftM2 (liftM2 (+)) .) . (. ((ap id .) . (. flip id) . (.) . (-))) . (.) . (.) . (+)): f made pointless by lambdabot Commented Nov 19, 2011 at 18:04

6 Answers 6

12

As bravit hints at, you can rewrite a non-recursive let using a lambda in the following way:

let x = A in B     ==>     (\x -> B) A 

where x is a variable and A and B are expressions.

Sign up to request clarification or add additional context in comments.

4 Comments

The thing I find funny about this trick is that it is actually a standard practice in Javascript since only functions can introduce a scope block there.
I'm still not sure I understand how is one able to reuse it
@Asaf: You can refer to x multiple times in B. For example, take (\x -> x + x) 3. This is equivalent to 3 + 3, except you only had to write the 3 once.
@Asaf Here's a hint: remember that the arguments to a lambda may themselves be functions.
8

To reuse something you can make it an argument to something.

Comments

2

I think the intention is what bravit hints at.
The smartypants follow-the-letters-of-the-law workaround is binding g with a case ;)

1 Comment

Another smartypants solution would be to make g a top-level function, since it doesn't close over anything from f :)
2

To expand on hammar's and bravit's hints, your solution is going to require not just one lambda, but two - one of which will look a great deal like g, and the other of which will look a great deal like the second half of f

Comments

1

Using lambda calculus g is (\x -> 2*x^2 + 10*x + 1)

So you need to substitute g with that in f x y z = x^3 - g (x + g (y - g z) + g (z^2))

$> echo "f x y z = x^3 - g (x + g (y - g z) + g (z^2))" | sed -r -e 's/g/(\\x -> 2*x^2 + 10*x + 1)/g'
f x y z = x^3 - (\x -> 2*x^2 + 10*x + 1) (x + (\x -> 2*x^2 + 10*x + 1) (y - (\x -> 2*x^2 + 10*x + 1) z) + (\x -> 2*x^2 + 10*x + 1) (z^2))

I'm just kidding, sorry.

2 Comments

I'm sure his instructors would be less than excited about that answer ;)
This is exactly the answer I'd give. As far as I know, the question boils down to "here, take this idiomatic code and make it worse, just to prove that you know X". If the teacher wants to check if I know X, they should pose a question where X is actually useful/necessary.
-1

That question seems kinda curious and interesting for me. So, I'm trying to figured out what is lambda calculus is, find an answer and want to show it to OP (all hints have already been showed actually, spoiler alert).

Firstly, lets try to redefine f:

λ> let f = (\g x y z -> x^3 - g(x + g(y - g z) + g(z^2)))
f ::
  (Integer -> Integer) -> Integer -> Integer -> Integer -> Integer

So, we've got function, which get function and 3 numbers and return the answer. Using curring we can add g definition right here, like f_new = f g:

λ> let f = (\g x y z -> x^3 - g(x + g(y - g z) + g(z^2))) (\x -> 2*x^2 + 10*x + 1)
f :: Integer -> Integer -> Integer -> Integer

We're done. Let's check it:

λ> f 0 0 0
-13

The answer is correct.

UPD:

In those examples let is just a way to declare function in the interpreter, so final answer is:

f :: Num a => a -> a -> a -> a
f = (\g x y z -> x^3 - g(x + g(y - g z) + g(z^2))) (\x -> 2*x^2 + 10*x + 1)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.