我有一個關於如何檢索Map
的最小值的問題。最小值在一個地圖haskell
我有一個Map k (Maybe a,Maybe b)
我需要檢索元組中第一個元素(最小的a
)上的值最小的鍵,但找不到任何預定義的函數。有一些我可以使用的功能,或者我應該自己實現嗎? 謝謝
我有一個關於如何檢索Map
的最小值的問題。最小值在一個地圖haskell
我有一個Map k (Maybe a,Maybe b)
我需要檢索元組中第一個元素(最小的a
)上的值最小的鍵,但找不到任何預定義的函數。有一些我可以使用的功能,或者我應該自己實現嗎? 謝謝
您將需要約束Ord a
。此外,您需要決定如何比較Just x
和Nothing
(因爲您必須將(Just x, y)
與(Nothing, z)
進行比較)。我假設你想要Just x
小於Nothing
所有x
。如果您使用toList
將地圖轉換爲列表,則可以使用自定義比較功能在列表上使用minimumBy
。此外,元組的第二部分(Maybe b
)是無關緊要的,所以我們只需要考慮Map k (Maybe a, b)
並獲得更一般的功能。
我建議是這樣
import qualified Data.Map as M
import Data.List
minimum' :: (Ord a) => M.Map k (Maybe a, b) -> k
minimum' = fst . (minimumBy comp) . M.toList
where
comp (_, (Nothing, _)) (_, (Just _, _)) = GT
comp (_, (Just _, _)) (_, (Nothing, _)) = LT
comp (_, (Nothing, _)) (_, (Nothing, _)) = EQ
comp (_, (Just x, _)) (_, (Just y, _)) = compare x y
這是很難說什麼樣的行爲,你真的想與問候到Nothing
S,但另一種更合理的(*),替代將是最小的功能返回類型爲Maybe k
,如果找到的最小元素(如上所示)爲(Nothing, _)
,則返回Nothing
。達到此目的的一種方法是首先用toList
返回filter
列表以消除所有值爲(Nothing, _)
的元素。
(*)讓Just x
小於Nothing
有點不好。當你尋找最大的元素時,你會希望的行爲與相反,所以它們都變得相當不穩定和醜陋。換句話說,當訂購類型a
時,類型Maybe a
只有部分有序(以自然的方式 - 當然,您可以強制執行總訂單,如上)。
您可能想要考慮的另一件事是,如果元組的第一個元素相等,該怎麼做。在這種情況下,您可能需要使用第二個元素作爲決勝盤。 – mhwombat
的確,但是這會引入'Ord b'約束,並且不清楚是否需要這種行爲。但絕對是需要考慮的一點。 – gspr
@isturdy:我認爲當mhwombat說「元組的第一個元素」時,他意味着* value *元組的第一個元素,而不是鍵值元組中的鍵。 – gspr