3

我有一个关于如何检索 a 的最小值的问题Map

我有一个Map k (Maybe a,Maybe b),我需要在元组的第一个元素(最小)上检索具有最小值的键a,但我找不到任何预定义的函数。有没有我可以使用的功能,或者我应该自己实现?谢谢

4

1 回答 1

5

您将需要约束Ord a。此外,您需要决定如何比较Just xand Nothing(因为您必须与 比较(Just x, y)(Nothing, z)。我假设你想要Just xNothingall更小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

很难说出您对Nothings 真正想要什么样的行为,但另一个更合理(*)的替代方法是让 minimum 函数具有 return type Maybe k,并Nothing在找到最小元素的情况下返回(如上)是(Nothing, _)。实现此目的的一种方法是首先filter从返回的列表toList中消除所有值为 的元素(Nothing, _)

(*) 让Just x小于Nothing有点不好。在寻找最大元素时,你会想要相反的行为,所以这一切都变得相当不一致和丑陋。换句话说,当类型a被排序时,类型Maybe a只是部分排序(以一种自然的方式——当然你可以强制一个全序,如上所述)。

于 2012-11-30T12:46:26.470 回答