Reputation: 418
Here i am trying to understand this function which folds a tree to one value. It shows that foldTree takes two functions as arguments, it applies first function to the element of the Tree a
and then passes the result to second function (b->b->b)
which again performs some operation and produces final result.
foldTree :: (a -> b) -> (b -> b -> b) -> Tree a -> b
foldTree f g (Leaf x) = f x
foldTree f g (Node tl tr) = g (foldTree f g tl) (foldTree f g tr)
I am trying following input to see how it works.
Input 1: foldTree (*2) (\x y -> x + y) (Leaf 6)
Input 2: foldTree (*2) (\x y -> x + y) (Node (Node (Leaf 1) (Leaf 2)) (Leaf 4))
It returns
Output 1 : 12
Output 2 : 14
The problem i am facing in understanding is where the second function argument operation is performed? and how it actually passes the values to the second function, apparently second function takes two values as arguments but first function only returns one value... from where the second value is passed? Can i say it took result of first function twice so that x
and y
values are same? because second function (\x y -> x + y)
takes two arguments? but then result would not be same as mentioned in output 1 and 2.
Secondly does it return the final result after performing second function or it returns the result after applying only the first function because i am confused even i removed second function it produces the same results.
Thirdly what is the purpose of g
here outside of two curly brackets? ***g*** (foldTree f g tl) (foldTree f g tr)
it took it as a Data constructor from the start or what? I know data constructor can be constructed as smart constructors but here how it treated.
I am so confused understanding this, may be i am complicating a lot of concepts in this one? Please don't hesitate to go into details.
Upvotes: 2
Views: 1118
Reputation: 116139
To understand the result of foldTree f g tree
you can use this technique:
tree
using the constructors, e.g. in your example we have (Node (Node (Leaf 1) (Leaf 2)) (Leaf 4))
.Leaf
with f
and Node
with g
. For the previous example, we get (g (g (f 1) (f 2)) (f 4))
.f
and g
to compute the result of the last expression. For the example, we get ((+) ((+) ((*2) 1) ((*2) 2)) ((*2) 4))
which is
((+) ((+) (1*2) (2*2)) (4*2))
which is ((1*2) + (2*2)) + (4*2)
which is (2+4)+8 = 14
.Note how we replace Leaf
a unary constructor with f
, a unary function, and Node
, a binary constructor with g
, a binary function. So, we always have the right number of arguments for our functions. More in general, the types will match just fine.
Upvotes: 4