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

Haskell 是否有一种简单的方法来处理Map k1(Map k2 v)类型的值,haskell,Haskell,我已经遇到这个问题好几次了,还没有找到任何标准的解决方案,所以我在这里问 举个具体的例子,假设我有一个单词对及其词性的列表(我正在做一个自然语言处理的家庭作业),并且我希望能够在给定词性的情况下,查找我遇到的单词的数量 有一个公认的解决方案吗?有什么建议吗?一个模板haskell库可以解决任意深度贴图的问题(嘿,我可以做梦,不是吗) 如果我正确理解了您的需求,您应该能够使用键成对的映射,例如map(k1,k2)v,或者在一般情况下使用键为任意长单词列表的映射,即map[k]v。如果元组和列表的内

我已经遇到这个问题好几次了,还没有找到任何标准的解决方案,所以我在这里问

举个具体的例子,假设我有一个单词对及其词性的列表(我正在做一个自然语言处理的家庭作业),并且我希望能够在给定词性的情况下,查找我遇到的单词的数量


有一个公认的解决方案吗?有什么建议吗?一个模板haskell库可以解决任意深度贴图的问题(嘿,我可以做梦,不是吗)

如果我正确理解了您的需求,您应该能够使用键成对的映射,例如
map(k1,k2)v
,或者在一般情况下使用键为任意长单词列表的映射,即
map[k]v
。如果元组和列表的内容实现了Ord,那么元组和列表都实现了Ord,所以这是开箱即用的

使用它应该比使用嵌套贴图方便得多。

如果
贴图(k1,k2)v
不合适(也许如果您需要提取和操作
贴图k2 v
s),那么定义复合贴图操作函数并不难。e、 g

lookup2 :: (Ord k1, Ord k2) => k1 -> k2 -> Map k1 (Map k2 v) -> Maybe v
lookup2 k1 k2 = lookup k2 <=< lookup k1

如果你能忍受一些间接的影响:

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
因此:


在特定的键序列之后编写插入、更新等函数虽然枯燥,但也很简单。

我需要能够获得给定k1的所有K2的信息。我知道我可以只进行筛选,但这似乎不是最好的解决方案。我的困难在于insertWith(我实际上不需要insertWithKey,但如果我能找到它就好了)。是的,
lookup2
可能是最容易编写的。请参见编辑我的
insertWith2
。也许稍后我会在TH中编写一个TH库作为练习:)如果我需要同时提供所有键,这并不是特别有趣(我可以使用一个元组)。如果给定的键少于必需的键,我会得到一个新的嵌套映射(如果键序列失败,则什么都没有)。那么,使用这种方法,您当然可以做到这一点,只需定义一个函数look::Ord k=>[k]->Nestedmap k v->Maybe(Nestedmap k v),它将返回一个用Val或Nest构造的值。与使用lookup2、lookup3等相比,它更容易接受任意级别的嵌套,例如:look[]n=Just n look(k:(u)(Val))=Nothing look(k:ks)(Nest m)=m.lookup k m>>=look ks
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