Tôi là người mới bắt đầu sử dụng Haskell. Giả sử tôi muốn viết một hàm convertKVList
lấy danh sách phẳng các cặp khóa-giá trị, trong đó một số khóa có thể được lặp lại và biến nó thành ánh xạ từ các khóa sang danh sách các giá trị trong đó tất cả các khóa là duy nhất. Ví dụ, trên một danh sách các cặp Int
s, tôi muốn hành vi này:Haskell: chuyển đổi danh sách cặp khóa-giá trị (a, b) (với các phím lặp lại có thể) thành danh sách (a, [b]) được nhóm theo khóa
> convertKVList [(1, 2), (1, 4), (1, 3), (2, 3)]
[(1,[3,4,2]),(2,[3])]
Điều này có vẻ giống như một nhiệm vụ đủ phổ biến mà có nên được một chức năng thư viện có sẵn để làm những gì tôi muốn, nhưng tôi couldn' t tìm thấy bất cứ điều gì khi tôi nhìn. Cuối cùng, có người đề nghị tôi soạn Map.toList
với Map.fromListWith (++)
, và tôi đã kết thúc với điều này:
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
Câu hỏi của tôi là dành cho Haskellers nhiều kinh nghiệm hơn và có hai phần: Thứ nhất, là thế này thế nào bạn sẽ đi về nó, hoặc có cách nào "tốt hơn" (dễ đọc hơn, hoặc hiệu quả hơn, hoặc cả hai)?
Thứ hai, làm thế nào tôi có thể tự mình làm điều này? Tôi biết rằng tôi muốn loại này là [(a, b)] -> [(a, [b])]
, nhưng việc đưa nó vào Hoogle không có ích gì cả. Và tôi đã xem các tài liệu Data.Map
, nhưng không phải fromListWith
cũng không phải toList
đã nhảy ra ngoài đặc biệt hữu ích. Vì vậy: làm thế nào bạn sẽ đi về suy nghĩ về vấn đề này? (Tôi nhận ra rằng cả hai câu hỏi này đều mang tính chủ quan, đặc biệt là câu hỏi thứ hai.)
Cảm ơn!
Cảm ơn, điều này rất hữu ích. Nó không xảy ra với tôi để làm bước của bạn (1), và vì vậy khi tôi nhìn vào 'fromListWith' trong tài liệu, tôi nghĩ nó trông giống như những gì tôi muốn, nhưng không hoàn toàn, bởi vì nó sẽ không cho tôi thay đổi loại thành phần thứ hai từ 'b' thành' [b] '. Tôi đoán một cách để nghĩ về nó là bước (1) là những gì tôi muốn làm gì nếu các phím đã được duy nhất và _all_ tôi đã làm là xoa bóp các loại vào '(a, [b])'. Vì vậy, nếu chúng ta đặt nó cùng với 'fromListWith', chúng ta đang ở gần nhất. –