Haskell自定义类型Show实例问题:构造器不在作用域及调用报错
Let's walk through your problems step by step:
1. The treeFromList [1,2,3] Runtime Error
The error you're seeing happens because of how treeFromList is defined. Its type signature is:
treeFromList :: (Ord a) => [a] -> BTree a -> BTree a
This means it expects two arguments: a list of values, and an initial tree to insert into. When you call treeFromList [1,2,3] without the second argument, Haskell returns a function of type BTree Integer -> BTree Integer instead of a concrete tree. Functions don't have a default Show instance, which triggers the error when you try to print it.
Fixes:
- Option 1: Pass an initial empty tree explicitly:
treeFromList [1,2,3] EmptyTree - Option 2: Refactor
treeFromListto start with an empty tree by default (this is more idiomatic):
Now you can calltreeFromList :: (Ord a) => [a] -> BTree a treeFromList = foldr treeInsert EmptyTreetreeFromList [1,2,3]directly, and it will return the built tree which can be printed (thanks to yourderiving Showclause).
2. Custom Show Instance Compilation Errors
Your attempt to define custom Show instances has a key misunderstanding: EmptyTree and Node are data constructors for the BTree a type, not separate types. You can't define Show instances for them individually—you need to define a single instance for the BTree a type, pattern-matching on its constructors.
Here's why your code failed:
- You tried to pattern-match on
BTree a, butBTreeis a type constructor (used to create types likeBTree Integer), not a data constructor (used to create values). - You tried to create instances for
EmptyTreeandNode, which aren't standalone types.
Correct Custom Show Instance Example
If you want a custom output format (instead of the auto-generated one from deriving Show), here's a valid implementation:
instance Show a => Show (BTree a) where show EmptyTree = "EmptyTree" show (Node left root right) = "Node (" ++ show left ++ ") " ++ show root ++ " (" ++ show right ++ ")"
This will produce output like:
Node (Node (EmptyTree) 1 (EmptyTree)) 2 (Node (EmptyTree) 3 (EmptyTree))
If you prefer a simpler format (like in-order traversal), you could write:
instance Show a => Show (BTree a) where show EmptyTree = "" show (Node left root right) = show left ++ " " ++ show root ++ " " ++ show right
Which would output:
1 2 3
Remember: since you already used deriving Show on your BTree type, you only need a custom instance if you want to change the default output format.
内容的提问来源于stack exchange,提问作者twigonometry

