我是一名Haskell初學者。假設我想編寫一個函數convertKVList
,該函數使用一系列鍵值對,其中一些鍵可能會重複,並將其轉換爲從鍵到值列表的映射,其中所有鍵都是唯一的。例如,對Int
s的名單上,我想這種行爲:Haskell:將(a,b)鍵值對(可能重複的鍵)列表轉換爲按鍵分組的列表(a,[b])
> convertKVList [(1, 2), (1, 4), (1, 3), (2, 3)]
[(1,[3,4,2]),(2,[3])]
這似乎是一個足夠常見的任務,就必須有可用的做我想做的庫函數,但我不能」當我看時,我找不到任何東西。最後,有人建議我撰寫Map.toList
與Map.fromListWith (++)
,我結束了與此:
import Data.Map as Map (toList, fromListWith)
convertKVList :: (Ord a) => [(a, b)] -> [(a, [b])]
convertKVList ls =
(Map.toList . Map.fromListWith (++) . map (\(x,y) -> (x,[y]))) ls
我的問題是更有經驗的Haskellers並分爲兩個部分:首先,這是你將如何去了解它,或有沒有「更好」(更容易閱讀,或更有效率,或兩者兼而有之)?
其次,我怎麼能自己想出這個呢?我知道我想要的類型是[(a, b)] -> [(a, [b])]
,但將它放入Hoogle中並沒有提供任何有用的信息。我曾看過Data.Map
文檔,但fromListWith
和toList
都沒有跳出來,因此特別有用。那麼,你將如何去思考這個問題呢? (我意識到這兩個問題都是主觀的,尤其是第二個問題。)
謝謝!
謝謝,這很有幫助。我沒有想到要做你的步驟(1),所以當我在文檔中查看'fromListWith'時,我認爲它看起來有點像我想要的,但並不完全,因爲它不會讓我將第二個組件的類型從'b'改爲'[b]'。我猜想有一種方法可以想到,如果鍵已經是唯一的,我所要做的就是步驟(1),而我所要做的就是將類型按到'(a,[b])'中。所以如果我們把它與'fromListWith'放在一起,我們就完成了大部分的工作。 – 2013-03-20 14:41:15