2011-11-19 35 views
3

我遇到過這個問題幾次,並沒有找到任何標準解決方案,所以我在這裏問。有沒有一種簡單的方法來處理類型爲Map k1(Map k2 v)的值

對於一個具體的例子,假設我有一個單詞對和他們的詞性對(我正在做一個自然語言處理家庭作業任務)的列表,我希望能夠給予一部分講話,查看我遇到的單詞的數量。

有沒有可以接受的解決方案?有什麼建議?一個模板haskell庫,可以解決這個任意的深度圖(嘿,我可以夢想,不能我)?

回答

2

如果Map (k1, k2) v不適合(也許如果您需要提取和操作Map k2 v s),那麼定義複合地圖操作函數並不難。例如

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 
+0

我的困難是在insertWith(我實際上並不需要insertWithKey,但如果我能弄清楚它會很好)。 –

+0

是的,'lookup2'可能是最容易寫的。請參閱我的'insertWith2'編輯。 – dave4420

+0

也許以後我會在TH中寫一個TH庫作爲練習:) –

3

如果我正確理解了您的要求,您應該能夠使用密鑰爲成對的地圖,例如, Map (k1, k2) v,或在一般情況下的地圖,其中的密鑰是任意長的單詞列表,即Map [k] v。如果元組和列表的內容都是Ord,那麼這個工作就可以直接使用。

這應該比嵌套地圖工作更方便。

+0

我需要能夠獲得關於給定k1的所有k2的信息。我知道我可以過濾,但這似乎不是最好的解決方案。 –

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 

這將是微不足道的,但枯燥,編寫插入,更新等功能,在特定的按鍵序列之後。

+0

如果我需要一次提供所有的鍵(我可以使用一個元組),這並不是特別有趣。如果給定少於必需的鍵時,我得到一個新的嵌套地圖(或者沒有,如果鍵序列失敗),它會更有用。 –

+0

那麼,你可以這樣做,只需定義一個函數look :: Ord k => [k] - > Nestedmap k v - > Maybe(Nestedmap k v),它將返回一個由Val或Nest構造的值。並且它會比使用lookup2,lookup3等更容易地接受任意級別的嵌套。 –

+0

例如: look [] n =只要n look(k:_)(Val _)= Nothing look(k:ks)( Nest m)= M.lookup km >> = look ks –

相關問題