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的未来版本中删除。请注意,最新的语言标准彻底删除了数据类型上下文。