我有一个关于如何检索 a 的最小值的问题Map
。
我有一个Map k (Maybe a,Maybe b)
,我需要在元组的第一个元素(最小)上检索具有最小值的键a
,但我找不到任何预定义的函数。有没有我可以使用的功能,或者我应该自己实现?谢谢
您将需要约束Ord a
。此外,您需要决定如何比较Just x
and Nothing
(因为您必须与 比较(Just x, y)
)(Nothing, z)
。我假设你想要Just x
比Nothing
all更小x
。如果您使用toList
将地图转换为列表,则可以minimumBy
在列表上使用自定义比较功能。此外,元组 ( ) 的第二部分Maybe b
是无关紧要的,所以我们只需调用 thinkMap 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 真正想要什么样的行为,但另一个更合理(*)的替代方法是让 minimum 函数具有 return type Maybe k
,并Nothing
在找到最小元素的情况下返回(如上)是(Nothing, _)
。实现此目的的一种方法是首先filter
从返回的列表toList
中消除所有值为 的元素(Nothing, _)
。
(*) 让Just x
小于Nothing
有点不好。在寻找最大元素时,你会想要相反的行为,所以这一切都变得相当不一致和丑陋。换句话说,当类型a
被排序时,类型Maybe a
只是部分排序(以一种自然的方式——当然你可以强制一个全序,如上所述)。