2

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]
0

2 Answers 2

4

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))
Sign up to request clarification or add additional context in comments.

3 Comments

I don't think the . is necessarily misplaced. OP could well have meant element x + (sum . map sumTree) (branch x). Indeed, to me that's what their whitespacing suggests.
@amalloy perhaps, though that would seem too advanced an error for someone confused about function call syntax. :) I think confusing . with $ is pretty common.
About reading those error messages, don't panic, take it slow, read them slowly and the meaning will become clearer. :)
2

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.