views:

91

answers:

1

Hi

I've defined a Tree data type in Haskell and an associated 'size' method which calculates the number of elements in the tree. This worked before, however I have updated the Tree data type to use named fields as in the following definition:

data Tree a = Empty
 | Leaf {value::a}
 | Node {left :: (Tree a), value :: a, right :: (Tree a)}
 deriving (Eq, Ord, Show)

I've found (by playing around in GHCi) that I can access a named field using the function (left n) for example. However, when I try to use this function I get an error:

size :: Tree a -> Int
size Empty    = 0
size (Leaf l)   = 1
size (Node n)   = size (left n) + 1 + size (right n)

GHCi simply says "Not in scope: left" and the equivalent for right. The Tree definition is in a module called Tree and the size definition is in a module called Main, but with the non-named fields I never had a problem with scope when it came to accessing variables from the Tree datatype.

+7  A: 

Your size (Node n) pattern needs to have a correct constructor. In your code n extracts the left element.

Try this (if you really want to use the named patterns):

size n@(Node _ _ _)   = size (left n) + 1 + size (right n)

Or even:

size n@(Node {})   = size (left n) + 1 + size (right n)

Or you can extract the labels in the pattern:

size (Node {left=l, right=r})   = size l + 1 + size r

or simply ignore the labels:

size (Node l _ r)   = size l + 1 + size r
0xfe
I've tried all of your suggestions but I still get the 'not in scope' error. I can use 'left' and 'right' in GHCi but can't seem to use them in my Main module.
benwad
Are you exporting the names in your module? (Those names are functions too). You need something like "module TreeModule (Tree Node Leaf left right)" in your module code.
0xfe
Thanks - I had omitted the left, right and value declarations from the code.
benwad
Or you could export like this: "module TreeModule (Tree(..))" which exports everything defined as part of the Tree data declaration.
MtnViewMark