Asaf
Asaf

Reputation: 8216

Reusing a Lambda function in Haskell

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?

Upvotes: 7

Views: 568

Answers (6)

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)

Upvotes: -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.

Upvotes: 1

Nate
Nate

Reputation: 12849

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

Upvotes: 2

hammar
hammar

Reputation: 139930

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.

Upvotes: 12

Daniel Fischer
Daniel Fischer

Reputation: 183978

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

Upvotes: 2

bravit
bravit

Reputation: 449

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

Upvotes: 8

Related Questions