我遇到過這個問題幾次,並沒有找到任何標準解決方案,所以我在這裏問。有沒有一種簡單的方法來處理類型爲Map k1(Map k2 v)的值
對於一個具體的例子,假設我有一個單詞對和他們的詞性對(我正在做一個自然語言處理家庭作業任務)的列表,我希望能夠給予一部分講話,查看我遇到的單詞的數量。
有沒有可以接受的解決方案?有什麼建議?一個模板haskell庫,可以解決這個任意的深度圖(嘿,我可以夢想,不能我)?
我遇到過這個問題幾次,並沒有找到任何標準解決方案,所以我在這裏問。有沒有一種簡單的方法來處理類型爲Map k1(Map k2 v)的值
對於一個具體的例子,假設我有一個單詞對和他們的詞性對(我正在做一個自然語言處理家庭作業任務)的列表,我希望能夠給予一部分講話,查看我遇到的單詞的數量。
有沒有可以接受的解決方案?有什麼建議?一個模板haskell庫,可以解決這個任意的深度圖(嘿,我可以夢想,不能我)?
如果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
如果我正確理解了您的要求,您應該能夠使用密鑰爲成對的地圖,例如, Map (k1, k2) v
,或在一般情況下的地圖,其中的密鑰是任意長的單詞列表,即Map [k] v
。如果元組和列表的內容都是Ord
,那麼這個工作就可以直接使用。
這應該比嵌套地圖工作更方便。
我需要能夠獲得關於給定k1的所有k2的信息。我知道我可以過濾,但這似乎不是最好的解決方案。 –
如果你能忍受一些間接:
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
這將是微不足道的,但枯燥,編寫插入,更新等功能,在特定的按鍵序列之後。
如果我需要一次提供所有的鍵(我可以使用一個元組),這並不是特別有趣。如果給定少於必需的鍵時,我得到一個新的嵌套地圖(或者沒有,如果鍵序列失敗),它會更有用。 –
那麼,你可以這樣做,只需定義一個函數look :: Ord k => [k] - > Nestedmap k v - > Maybe(Nestedmap k v),它將返回一個由Val或Nest構造的值。並且它會比使用lookup2,lookup3等更容易地接受任意級別的嵌套。 –
例如: look [] n =只要n look(k:_)(Val _)= Nothing look(k:ks)( Nest m)= M.lookup km >> = look ks –
我的困難是在insertWith(我實際上並不需要insertWithKey,但如果我能弄清楚它會很好)。 –
是的,'lookup2'可能是最容易寫的。請參閱我的'insertWith2'編輯。 – dave4420
也許以後我會在TH中寫一個TH庫作爲練習:) –