假设我有以下数据类型:
data BinaryTree a = EmptyTree | Node a (BinaryTree a) (BinaryTree a) deriving (Eq, Ord, Show)
以及以下功能
member a EmptyTree = False
member a (Node x l r)
| a < x = member a l
| a > x = member a r
| a == x = True
此功能有效。
检查Node
的类型:
:t Node
Node :: a -> BinaryTree a -> BinaryTree a -> BinaryTree a
但是,如果成员函数被赋予签名:
member :: Node a -> BinaryTree a -> Bool
(类型a的Node
和生成BinaryTree
的类型a的Bool
它出错了:
Not in scope: type constructor or class ‘Node’
A data constructor of that name is in scope; did you mean DataKinds?
为什么?如何定义接受(和比较)任意类型的节点和树的函数?
答案 0 :(得分:7)
Node
不是一种类型;这是一个:
BinaryTree
类型的值a -> BinaryTree a -> BinaryTree a -> BinaryTree a
)两者的确意味着相同,但在两种不同的环境中实现外观可能会有所帮助,即模式匹配和构造。
你的member
函数最有可能只需要元素来检查它的存在:
member :: a -> BinaryTree a -> Bool
如果您需要a
的其他约束(在二叉树的情况下,它将是Ord
和Eq
,很可能,您也必须将它们放在那里
member :: (Ord a, Eq a) => a -> BinaryTree a -> Bool