首页 > 解决方案 > 如何在 Haskell 中从 Set 中提取具有零个或一个元素的元素?

问题描述

问题:

假设我们有一个带有零个或一个元素的Set of 。a如果它存在,我们需要获取这个元素。

Set a -> Maybe a在hoogle上搜索了函数,发现了以下函数:

lookupMin :: Set a -> Maybe a

lookupMax :: Set a -> Maybe a

问题:

a在这种情况下,惯用的方法是什么?

我应该使用模式匹配还是这些功能之一?

标签: haskellset

解决方案


要将一些评论移到答案中并添加我自己的 2¢:

我发现两者都是lookupMin单调lookupMax的,因为他们对我作为读者说“从集合中获取最小/最大元素(如果有)”,而我们的意图更多是“从集合中获取任意元素(如果有)” . 这种意图读取从根本上复杂化,因为 aSet不是真正的 0-or-1- 类型a,实际上那是 a Maybe

AJFarmer 建议head :: (Foldable f) => f a -> Maybe a我同意这是一个好的名称和类型,但它来自另一个前奏曲(protolude)。您可以轻松地自己实现它,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

正如 chi 所说,你不能在 上进行模式匹配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

如果您只需要一个功能,这可能有点过分了。


推荐阅读