Stinkidog
Stinkidog

Reputation: 435

Binary Tree Fold Functions

I have the definition of a Binary tree in Haskell as the following:

data BTree x = Nil | BNode x (BTree x) (BTree x)

I then have a fold definition for this data type:

foldB :: (x -> u -> u -> u) -> u -> BTree x -> u
foldB f a Nil = a
foldB f a (BNode x l r) = f x (foldB f a l)(foldB f a r)

So I hoped that I could simply make this function to sum all the values:

sumBFold :: (Num a) => BTree a -> a
sumBFold x = foldB (+) 0 x

But this does not work, and I cannot for the life of me figure out why. The useful part of the error message I'm getting is:

Couldn't match type `a` with `a -> a'
`a' is a rigid type variable bound by the type signature for:
sumBFold :: forall a. Num a => BTree a -> a
Expected type: (a -> a) -> a -> a -> a
Actual type: (a -> a) -> (a -> a) -> a -> a
In the first argument of folB namely `(+)`

Upvotes: 0

Views: 251

Answers (1)

ephemient
ephemient

Reputation: 204718

The error comes about from trying to use

(+) :: (Num a) => a -> a -> a

as a parameter with type

(x -> u -> u -> u)

If you start trying to fit it in, remembering that (x -> u -> u -> u) is the same as (x -> (u -> (u -> u))),

x == a
u == a
u -> u == a -> a == a

which is impossible, and where the error comes from.

Consider any of the following.

sumBFold :: (Num a) => BTree a -> a
sumBFold = foldB add3 where add3 x y z = x + y + z
sumBFold = foldB $ \x y z -> x + y + z
sumBFold = foldB ((.) (+) . (+))

Upvotes: 1

Related Questions