我们使用IntMaps在Haskell中实现Tries。但是,我似乎无法想象出IntMaps。
以下是我所拥有的:
charMapLookup :: Char -> IntMap a -> Maybe a
charMapLookup c dict = IntMap.lookup (ord c) dict
charMapInsert :: Char -> a -> IntMap a -> IntMap a
charMapInsert c v dict = IntMap.insert (ord c) v dict
-- Question 1.
data Trie a = TrieOf (Maybe a) (IntMap (Trie a))
deriving Show
trieLookup :: [Char] -> Trie a -> Maybe a
-- My code
trieLookup [] (TrieOf a t) = a
trieLookup (x:xs) (TrieOf _ t) = trieLookup xs (charMapLookup x t)
trieInsert :: [Char] -> a -> Trie a -> Trie a
trieInsert [] a (TrieOf c t)= TrieOf c t
trieInsert (x:xs) a (TrieOf c t) | isNothing (charMapLookup x t) = trieInsert xs a (charMapInsert x Nothing t)
| trieInsert xs a (charMapLookup x t)
这似乎对我有意义,因为如果字符串中没有任何内容,则返回节点的值,否则在相关子树中搜索字符串的尾部,并且类似于插入但是,当我尝试运行它时:
Couldn't match expected type ‘Trie a’
with actual type ‘Maybe (Trie a)’
Relevant bindings include
t :: IntMap (Trie a)
trieLookup :: [Char] -> Trie a -> Maybe a
In the second argument of ‘trieLookup’, namely
‘(charMapLookup x t)’
In the expression: trieLookup xs (charMapLookup x t)
Failed, modules loaded: none.
Couldn't match expected type ‘Trie a’
with actual type ‘IntMap (Maybe a0)’
Relevant bindings include
t :: IntMap (Trie a)
c :: Maybe a
a :: a
trieInsert :: [Char] -> a -> Trie a -> Trie a
In the third argument of ‘trieInsert’, namely
‘(charMapInsert x Nothing t)’
In the expression: trieInsert xs a (charMapInsert x Nothing t)
Couldn't match type ‘Trie a’ with ‘Maybe a0’
Expected type: IntMap (Maybe a0)
Actual type: IntMap (Trie a)
Relevant bindings include
t :: IntMap (Trie a)
c :: Maybe a
a :: a
trieInsert :: [Char] -> a -> Trie a -> Trie a
In the third argument of ‘charMapInsert’, namely ‘t’
In the third argument of ‘trieInsert’, namely
‘(charMapInsert x Nothing t)’
我不确定如何修复错误,我知道它说类型不匹配,但t
应该是Tries的IntMap(对吧?)所以我我不知道如何处理这个问题。我花了很长时间试图解决这个问题,任何可以解决问题的代码都会受到极大的赞赏。谢谢!
答案 0 :(得分:2)
构造第一条错误消息。它发生在trieLookup中,当您获取对应于第一个符号的分支并继续查找密钥的其余部分时。问题是,这个分支不是Trie a
而是Maybe (Trie a)
(第一个字符可以在根中取消映射)。要继续查找,您需要将其平面映射到可能不合适的分支:
trieLookup (x:xs) (TrieOf _ t) = (charMapLookup x t) >>= trieLookup xs
(或使用case
代替>>=
,这将处理Nothing
的{{1}}和Just branch
可能结果。
请注意,除了类型错配之外,您的代码还包含更多错误,在编译器输出中未列出:
charMapLookup
这场比赛的RHS与原来的trie相同,没有变化。
trieInsert (x:xs) a (TrieOf c t) | isNothing (charMapLookup x t) = trieInsert xs a (charMapInsert x Nothing t) | otherwise = trieInsert xs a (charMapLookup x t)