Fairly new to Haskell and trying to wrap my head around user defined classes and, after lots of messing around and reading learnyouahaskell, I managed to define the following class for a binary tree:
data BTree a = EmptyTree | Node (BTree a) a (BTree a) deriving (Ord, Eq, Show)
{- compares value of new node x to root
if same, don't insert (no duplicates); if smaller, insert into left subtree lSub; if larger, insert into right subtree rSub -}
treeInsert :: (Ord a) => a -> BTree a -> BTree a
treeInsert x EmptyTree = Node EmptyTree x EmptyTree
treeInsert x (Node lSub root rSub)
| x == root = Node lSub x rSub
| x < root = Node (treeInsert x lSub) root rSub
| x > root = Node lSub root (treeInsert x rSub)
--recurses over list of nodes to add
treeFromList :: (Ord a) => [a] -> BTree a -> BTree a
treeFromList [] tree = tree
treeFromList (node:nodes) tree = treeFromList nodes (treeInsert node tree)
The code above compiles, but when I try to run the following:
treeFromList [1,2,3]
I get an error saying "No instance for (Show (BTree Integer -> BTree Integer)) arising from a use of `print'"
So I tried to define some instances of show (working from a stack overflow post on a similar example)
instance Show (BTree a) where
show (BTree a) = show a
instance Show EmptyTree where
show (EmptyTree) = ""
instance Show (Node (BTree a) a (BTree a)) where
show (Node (BTree a) b (BTree c)) = show BTree a ++ " " ++ b ++ " " ++ show BTree c
But the code doesn't compile and all of my reference to either BTree, Node, or EmptyTree give the error "Not in scope: data constructor"
I can't figure out why they wouldn't be in scope, so I'm wondering if my definition of the instances are wrong somehow. Thanks in advance for any help
treeFromList
as taking 2 inputs, a list and a tree, while calling it with just the first, list argument. So how do you want this function to behave? The name to me implies that it should take a list and output a tree, and the way you called it suggests you want it to work that way. But in this case your definition is wrong. (It looks to me that what you have should be a helper function internal to the function, and the main function should call that withEmptyTree
as the second argument.) – Robin ZigmondtreeFromList
is "just"execState . traverse (modify . treeInsert)
. – chepnertreeFromList = flip (foldl' (flip treeInsert))
. – chepner