Reputation: 23
I defined my own rose tree and tried to sum its content. All the types match, but it fails to compile for an unknown reason.
That's my piece of code:
data Tree a = Tree {element :: a, branch :: [Tree a]} deriving (Show)
sumTree :: (Num a) => Tree a -> a
sumTree x = element(x) + sum.map (sumTree) branch(x)
I am getting these errors:
Prelude> ::l tree.hs
[1 of 1] Compiling Main ( tree.hs, interpreted )
tree.hs:3:32: error:
• Couldn't match expected type ‘Tree a -> t0 a’
with actual type ‘[b0]’
• The function ‘map’ is applied to three arguments,
but its type ‘(Tree b0 -> b0) -> [Tree b0] -> [b0]’ has only two
In the first argument of ‘sum’, namely ‘(map (sumTree) branch (x))’
In the second argument of ‘(+)’, namely
‘(sum (map (sumTree) branch (x)))’
• Relevant bindings include
x :: Tree a (bound at tree.hs:3:9)
sumTree :: Tree a -> a (bound at tree.hs:3:1)
|
3 | sumTree x = element(x) + (sum (map (sumTree) branch(x)))
| ^^^^^^^^^^^^^^^^^^^^^^^
tree.hs:3:46: error:
• Couldn't match expected type ‘[Tree b0]’
with actual type ‘Tree a0 -> [Tree a0]’
• Probable cause: ‘branch’ is applied to too few arguments
In the second argument of ‘map’, namely ‘branch’
In the first argument of ‘sum’, namely ‘(map (sumTree) branch (x))’
In the second argument of ‘(+)’, namely
‘(sum (map (sumTree) branch (x)))’
|
3 | sumTree x = element(x) + (sum (map (sumTree) branch(x)))
| ^^^^^^
When clearly
Prelude> :t branch
branch :: Tree a -> [Tree a]
Upvotes: 2
Views: 60
Reputation: 71065
Parentheses in Haskell serve for grouping of code elements only. Haskell function call syntax is not f(x)
, it is simply f x
.
You wrote
sumTree x = element(x) + sum.map (sumTree) branch(x)
which is the same as
sumTree x = element x + sum . map sumTree branch x
but you meant
sumTree x = element x + sum . map sumTree (branch x)
The dot is still misplaced, you wanted it to be
sumTree x = element x + (sum $ map sumTree (branch x))
which is the same as
sumTree x = element x + sum (map sumTree (branch x))
Upvotes: 4
Reputation: 476699
You here applied the map
on the branch :: Tree -> Tree a
function, instead of the result of branch x
. This is due to the fact that te parenthesis are written in the wrong way.
You can implement your function as:
sumTree :: Num a => Tree a -> a
sumTree x = element x + sum (map sumTree (branch x))
Here we thus call map
with sumTree
and (branch x)
as parameters.
Here branch x
will thus generate the list of branches, we then call map sumTree
on that list to generate the sum of each subtree, and then we sum these up with sum
. We then add element x
to the result.
Upvotes: 2