Чтобы переместить некоторые комментарии в ответ и добавить свои собственные 2 ¢:
Я нахожу и lookupMin
, и lookupMax
неидиоматическими, потому что они, как читатель, говорят мне: "возьми мне элемент min / max (если есть) из набора", в то время как наше намерение больше "получи меня произвольно элемент (если есть) из набора ". Это чтение намерений существенно усложняется тем фактом, что Set
не совсем правильный тип 0-или-1- a
с, на самом деле это Maybe
.
AJFarmer предлагает head :: (Foldable f) => f a -> Maybe a
, что, я согласен, является хорошим именем и типом, но это из альтернативной прелюдии (протолуда). Вы можете легко реализовать это самостоятельно, listToMaybe . toList
все из базовых библиотек, хотя тогда вам нужно будет найти имя для него.
Объективы предоставляют другое решение, (^? _Wrapped . _head)
.
Если наше намерение читается лучше как «проверим, является ли он одноэлементным, и если да, извлеките элемент», тогда мы можем, возможно, сделать лучше.
fromSingleton :: Set a -> Maybe a
fromSingleton s = case toList s of
[a] -> Just a
_ -> Nothing
Или, может быть,
fromSingleton :: Set a -> Maybe a
fromSingleton (toList -> [x]) = Just x
fromSingleton _ = Nothing
Как говорит Чи, вы не можете сопоставлять с шаблоном на Set
, но, если хотите, вы можете установить для этого синонимы шаблонов, например.
pattern Empty <- (Set.toList -> [])
pattern Singleton x <- (Set.toList -> [x])
pattern Many xs <- (Set.toList -> xs@(_:_:_))
fromSingleton :: Set a -> Maybe a
fromSingleton (Singleton x) = Just x
fromSingleton _ = Nothing
Это, вероятно, излишне, если вам нужна только одна функция.