Haskell:难以将上下文(Eq a)嵌入到数据声明中

Haskell:难以将上下文(Eq a)嵌入到数据声明中,haskell,Haskell,我正在以下程序中编写一个简单的哈希树结构hash\u lookup.hs: module Main where data (Eq a) => HashTable a b = HashChildren (a, [HashTable a b]) | Hash (a, b) deriving (Show) getKey :: HashTable a b -> a getKey (HashChildren (k, hs)) = k getKey (Has

我正在以下程序中编写一个简单的哈希树结构
hash\u lookup.hs

module Main where

    data (Eq a) => HashTable a b = HashChildren (a, [HashTable a b]) | Hash (a, b) deriving (Show)

    getKey :: HashTable a b -> a

    getKey (HashChildren (k, hs)) = k
    getKey (Hash (k, h)) = k

    lookUp :: [a] -> HashTable a b -> Maybe (HashTable a b)

    lookUp [] table = return table
    lookUp _ (Hash _) = Nothing
    lookUp (p:path) (HashChildren (_, ts) ) = lookUp path ( head ( dropWhile (\x -> (getKey x) /= p) ts ) )
getKey用于检索给定哈希表的根键,lookUp采用字符串列表,并遵循它找到的第一条路径,直到它到达完整路径或失败(我知道这不是树的自然行为,但这是我的教程想要的)

我有两个问题: 1) 为什么我会收到一条错误消息,告诉我不允许使用
a/=a
(从最后一行开始),因为(Eq a)(终端中的错误消息)没有实例,尽管数据声明中有
(Eq a)

2) 除了我得到的错误和查找函数看似奇怪的行为之外,这是好的还是惯用的Haskell

感谢

Haskell中的一个常见“陷阱”是,如果在
数据
声明上设置类约束,使用该类型的每个函数也必须具有类约束。因此,您的
数据
声明在Haskell中不是惯用的,您应该消除它的类约束。无论如何,在
数据
声明中声明类约束不会给您带来任何好处


基本上,函数类型必须重复类约束。否则,函数的用户如何知道他们必须使用相关类的实例?请注意,您可以将函数
f
定义为函数
g
定义为
h
,该函数是根据您的
HashTable a b
类型定义的,这样
f
就不会提到您的
HashTable
类型,但是,由于类型依赖性,它需要一个类型为
a
的参数,该参数间接并最终用作
哈希表
类型的第一个参数<代码>f
的类型必须具有类约束,Haskell正确地推断出这一点,如果类型注释没有,它将拒绝您的类型注释。

数据类型上下文功能将在Haskell的未来版本中删除。请注意,最新的语言标准彻底删除了数据类型上下文。