是否有一种简单的方法来处理Map k1(Map k2 v)类型的值

时间:2011-11-19 06:16:55

标签: haskell

我已经遇到过这个问题几次并且没有找到任何标准解决方案,所以我在这里问。

对于一个具体的例子,假设我有一对单词和他们的词性列表(我正在做一个自然语言处理作业),我希望能够,给出一个词性,查看我遇到的单词的数量。

是否有可接受的解决方案?有什么建议?一个模板haskell库,解决了任意深度图(嘿,我可以做梦,不是我)?

3 个答案:

答案 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

在特定的键序列之后编写插入,更新等函数会很无聊,但很无聊。

相关问题