i have one Haskell function, which i don't understand but want to.
i :: Int
i = ((\g x -> g x + g x) (\y -> y)) 3
I know what a lambda function is: a nameless function.
E.g. (\x -> x) 3 takes 3 and returns it, (\x y -> x+y) 3 4 takes 3, 4 and returns 7.
But in this special case i can't interpret it. I hope you can help me.
Btw. the solution for this function is 6.
Now your (\y -> y) function is equivalent to id. Let's rewrite your function using that:
i = ((\g x -> g x + g x) id) 3
Now apply the id function to (\g x -> g x + g x). This will get reduced to:
i = (\x -> id x + id x) 3
Now it's simple:
i = id 3 + id 3
i = 6
(\g x -> g x + g x) takes the arguments g, which must be a function, and x, which must be a valid argument to that function, and then adds the result of applying g to x to itself.
In this case \y -> y is supplied as the value for g and 3 as the value for x, so we get (\y -> y) 3 + (\y -> y) 3. (y -> y) 3 is 3, so we get 3 + 3, which is 6.
Related
In my lecture, we had to define the function squareOn such that
with foldr.
The answer was
squareOn :: (Eq a, Num a) => [a] -> a -> a
squareOn = foldr (\x acc y -> if y == x then x*x else acc y) id
I undestand how foldr works, but I'm new at lambda expressions in Haskell. Is acc any type of function from Haskell? It would be nice if someone could explain how squareOn works. :)
This is a sort-of advanced usage of foldr. Normally, we see foldr used as in
fun xs = foldr (\x acc -> something using x and acc) base xs
or equivalently
fun = foldr (\x acc -> something using x and acc) base
which corresponds to the following recursive function:
fun [] = base
fun (x:xs) = something using x and acc
where acc = fun xs
Your case is a special case of this usage, where base, acc, and something using x and acc are functions. That is, we have
fun [] = \y -> base'
fun (x:xs) = \y -> something using x, acc, y
where acc = \y -> fun xs y
Moving back to foldr, we get
fun = foldr (\x acc -> \y -> something using x, acc, y) (\y -> base')
which can also be written as
fun = foldr (\x acc y -> something using x, acc, y) (\y -> base')
where a somehow confusing three-argument function appears to be passed to foldr.
Your specific case,
squareOn = foldr (\x acc y -> if y == x then x*x else acc y) id
corresponds to the explicit recursion:
squareOn [] = id
squareOn (x:xs) = \y -> if y == x then x*x else acc y
where acc = \y -> squareOn xs y
or
squareOn [] y = y
squareOn (x:xs) y = if y == x then x*x else squareOn xs y
which you should be able to understand.
Let's define this function without a lambda.
squareOn :: (Eq a, Num a) => [a] -> a -> a
squareOn = foldr f id
where
f x acc = g
where
g y | x == y = x * x
| otherwise = acc y
Now it's become what foldr usually looks like. It takes a function taking two arguments f and an initial value id.
When you pass [2, 4] to squareOn, it'll be expanded to foldr f id [2, 4], then f 2 (f 4 id) by the definition of foldr.
f 4 id returns a function that takes one argument y which returns 4 * 4 if y is 4, and returns id y otherwise. Let's call this function p.
p y | 4 == y = 4 * 4
| otherwise = id y
Now, f 2 (f 4 id) returns a function that takes one argument y which returns 2 * 2 if y is 2, and returns p y otherwise. When you name it q, it'll be like this.
q y | 2 == y = 2 * 2
| otherwise = p y
So squareOn [2, 4] 3, for example, is equivalent to q 3.
Whoever skipped those explicit arguments just made it unnecessarily harder on yourself to learn this stuff. It's totally superficial. Adding the explicit arguments, as specified by the type signature, gives us
squareOn :: (Eq a, Num a) => [a] -> a -> a
squareOn = foldr (\x acc y -> if y == x then x*x else acc y) id
squareOn xs = foldr (\x acc y -> if y == x then x*x else acc y) id xs
squareOn xs y = foldr (\x acc y -> if y == x then x*x else acc y) id xs y
squareOn xs y = foldr g id xs y where { g x acc y | y == x = x*x
| otherwise = acc y }
squareOn xs y = (case xs of {
[] -> id ;
(x:xs2) -> g x (foldr g id xs2)
}) y where { g x acc y | y == x = x*x
| otherwise = acc y }
Now we can see everything in play here, as opposed to having to keep it all in mind. There is playing chess, and then there's playing blindfold chess, and why play it blindfolded if you can just see?
So now it becomes obvious that passing that y around(*) from call to call unchanged actually has no purpose here, because it is the same y, and it is already in scope:
squareOn xs y = (case xs of {
[] -> y ;
(x:xs2) -> g x (foldr g y xs2)
}) where { g x acc | y == x = x*x
| otherwise = acc }
which simplifies back as just
squareOn xs y = foldr g y xs where { g x acc | y == x = x*x
| otherwise = acc }
{- cf.
squareOn xs y = foldr g id xs y where { g x acc y | y == x = x*x
| otherwise = acc y } -}
And to be pointlessly short and pointfree, like your original code,
squareOn = flip (foldr g) where { g x acc | y == x = x*x
| otherwise = acc }
Or it could be simplified to
squareOn xs y = case xs of {
[] -> y ;
(x:_) | y == x -> x*x ;
(_:xs2) -> squareOn xs2 y }
and further to a worker/wrapper with nested unary worker, whichever is clearer for you.
Passing the unchanged quantity around to have it in scope is only really needed in languages without nested scope, like Prolog.
(*)(so that explanation in full, which you asked for, about how this technique works, is actually in the linked answer).
I have the following code which gives out [2,4,6] :
j :: [Int]
j = ((\f x -> map x) (\y -> y + 3) (\z -> 2*z)) [1,2,3]
Why? It seems that just the "z-function" is being used, what happens to the "y-function"?
And how does map work in this particular case?
Let's compute:
((\f x -> map x) (\y -> y + 3) (\z -> 2*z)) [1,2,3]
^^^ f ^^^^^^^ ^^^ x ^^^^^
=
(map x) [1,2,3]
where f = \y -> y +3
x = \z -> 2*z
=
[x 1,x 2,x 3]
where f = \y -> y +3
x = \z -> 2*z
=
[2*1,2*2,2*3]
where f = \y -> y +3
x = \z -> 2*z
=
[2,4,6]
where f = \y -> y +3
x = \z -> 2*z
As we can see, f was taken as an argument, but was never used after that. Consequently \y -> y+3 never affected the final result.
The function map x is the function that applies function x to each element of a list. Note that, above, (map x) [1,2,3] is the same as map x [1,2,3]. Indeed, each function application g x1 x2 x3 x4 can be equivalently written as (((g x1) x2) x3) x4 by left-associating the applications.
I know that (.) f g x = f (g x). Suppose f has type Int -> Int, g has type Int -> Int -> Int. Now let h be defined by h x y = f (g x y). Which of the following statements are true and why (why not)?
a. h = f . g
b. h x = f . (g x)
c. h x y = (f . g) x y
Supposedly, only b. is true, while the others are false. I would think a. and b. are equivalent... a. is saying two functions are equal. Two functions are equal only iff when I add an argument to the end of both sides, it will still be equal. So I get h x = f . g x. Now (.) is an operator, so functional application takes precedence over it, so f . g x = f . (g x), which is b.
This looks like a homework, so I won't give the answer of which one is correct.
You consider a and b as identical incorrectly. If f . g is applied to x, you get (from the definition of (.))
(f . g) x = f (g x)
But b is f . (g x), which doesn't expand to f (g x). If you follow b through using the definition of (.), you will see the sense in the comments of the others.
Function composition's initial definition is a bit confusing, so I'll write it a different way:
f . g = \a -> f (g a)
This means that f . g returns a function which first applies the argument to g, then applies the result of that to f. This is also clear in the type signature:
(.) :: (b -> c) -> (a -> b) -> (a -> c)
Now for your function h, it has a type of something like h :: a -> a -> a. Remember that -> is right-associative, so the type could be written as h :: a -> (a -> a). Essentially, h :: a -> b, though this type would cause an error because b and a are uninferrable. (.) will only allow one argument to be applied to the first function, so:
-- One could write,
h x y = f (g x y)
-- But One could also write
h x = f . g x
-- Or, more clearly:
h x = (f) . (g x)
This is because Haskell functions are curried, so we can apply some arguments to g without fully evaluating it.
If we imagine what would happen if we applied (.) visually, then simplify, we can see how it works:
h x = \a -> f ((g x) a)
h x = \a -> f (g x a)
h x a = f (g x a)
So yes, b is the answer. This is because (.) only allows one argument to be applied to the first function before moving to the next.
Now you're job can be tackling the other incorrect solutions by simplifying as I have. It's not too difficult.
flip' :: (a -> b -> c) -> (b -> a -> c)
flip' f = g
where g x y = f y x
I want to ask that in the above flip' function , it seems that flip' will return a function named g and g x y share the same value with f y x
however, in " where g x y = f y x " , f y x is a function call and will return a value, g x y will aslo return a value, so does it make sense that " where v2 = v1 "?
I know that the code will work but I want to know more about the way it make this happen.
does anybody has an idea? thank you so much
In where g x y = f y x, g x y is not a function call g with parameters x and y. It is a declaration of the function g as a function taking 2 arguments x and y and evaluation to f y x.
So it means flip' given a function f taking 2 arguments will evaluate to g. g itself being defined as swapping two arguments to call f.
I have two functions f and g and I am trying to return f(g(x)) but I do not know the value of x and I am not really sure how to go about this.
A more concrete example: if I have functions f = x + 1 and g = x * 2 and I am trying to return f(g(x)) I should get a function equal to (x*2) + 1
It looks like you have it right, f(g(x)) should work fine. I'm not sure why you have a return keyword there (it's not a keyword in ocaml). Here is a correct version,
let compose f g x = f (g x)
The type definition for this is,
val compose : ('b -> 'c) -> ('a -> 'b) -> 'a -> 'c = <fun>
Each, 'a,'b,'c are abstract types; we don't care what they are, they just need to be consistent in the definition (so, the domain of g must be in the range of f).
let x_plus_x_plus_1 = compose (fun x -> x + 1) (fun x -> x * 2)