我已经遇到过这个问题几次并且没有找到任何标准解决方案,所以我在这里问。
对于一个具体的例子,假设我有一对单词和他们的词性列表(我正在做一个自然语言处理作业),我希望能够,给出一个词性,查看我遇到的单词的数量。
是否有可接受的解决方案?有什么建议?一个模板haskell库,解决了任意深度图(嘿,我可以做梦,不是我)?
答案 0 :(得分:3)
如果我正确理解了您的要求,您应该能够使用按键成对的地图,例如Map (k1, k2) v
,或者在一般案例图中,其中键是任意长的单词列表,即Map [k] v
。如果元组和列表的内容都是Ord
,那么它们就会实现,所以这可以直接使用。
使用它比嵌套地图更方便。
答案 1 :(得分:2)
如果Map (k1, k2) v
不合适(可能需要提取和操作Map k2 v
),那么定义复合Map操作函数并不难。 e.g。
lookup2 :: (Ord k1, Ord k2) => k1 -> k2 -> Map k1 (Map k2 v) -> Maybe v
lookup2 k1 k2 = lookup k2 <=< lookup k1
但是我不知道任何模板haskell库为你生成这些函数,抱歉。
编辑以下是我insertWith
的类似物:
insertWith2 :: (Ord k1, Ord k2) => (v -> v -> v) -> k1 -> k2 -> v -> Map k1 (Map k2 v) -> Map k1 (Map k2 v)
insertWith2 f k1 k2 m = insert k1 (insertWith f k2 v $ fromMaybe empty $ lookup k1 m) m
答案 2 :(得分:0)
如果你能站在一边:
import qualified Data.Map as M
import Control.Monad
data Ord k => Nestedmap k v = Val v | Nest (M.Map k (Nestedmap k v))
-- return Nothing is the list of keys is either too long or too short.
-- might be better to signal this kind of error some other way,
-- to distinguish between this and a key not being present.
look :: Ord k => [k] -> Nestedmap k v -> Maybe v
look [] (Val v) = Just v
look _ (Val _) = Nothing
look [] _ = Nothing
look (k:ks) (Nest m) = M.lookup k m >>= look ks
所以:
*Main Data.Map> let m = Nest $ fromList [("foo", Val 3), ("bar", Nest $ fromList [("foo", Val 4), ("baz", Nest $ fromList [("quux", Val 5), ("foo", Val 9)])])]
*Main Data.Map> look ["bar","baz","quux"] m
Just 5
在特定的键序列之后编写插入,更新等函数会很无聊,但很无聊。