Haskell:catMaybe for Data.Set?

时间:2011-02-23 10:19:58

标签: haskell set maybe

你将如何为Data.Set实现catMaybes?

我想出了:

import qualified Data.Set as Set
import qualified Data.Maybe as Maybe
setCatMaybes a = Set.map Maybe.fromJust . Set.delete Nothing $ a

fnord = Set.fromList [Nothing, Just 41, Just 43, Just 47]

然后我得到以下

setCatMaybes fnord == fromList [41,43,47]

3 个答案:

答案 0 :(得分:3)

我认为你已经拥有的解决方案可能是最好的解决方案。按照John的解决方案,这里有一个相当短的解决方案:

setCatMaybes :: Ord a => Set.Set (Maybe a) -> Set.Set a
setCatMaybes s = Set.fromAscList [x | Just x <- Set.toAscList s]

或者这是一个更长的,可能更快:

setCatMaybes2 :: Ord a => Set.Set (Maybe a) -> Set.Set a
setCatMaybes2 s
  | Set.null s = Set.empty
  | otherwise  = Set.mapMonotonic Maybe.fromJust $ case Set.deleteFindMin s of
                   (Nothing, s') ->  s'
                   _ -> s

答案 1 :(得分:2)

由于Set (Maybe a)是一种奇怪的类型,只有在应用f :: a -> Maybe b之后出现,为什么不一石二鸟并为mapMaybe创建Data.Set

import qualified Data.Set
import qualified Data.Maybe

mapMaybe :: Ord b => (a -> Maybe b) -> Data.Set.Set a -> Data.Set.Set b
mapMaybe f = Data.Set.fromList . Data.Maybe.mapMaybe f . Data.Set.toList

通过这种方式,奇怪的Set (Maybe a)永远不会存在。

答案 2 :(得分:0)

这个怎么样:

setCatMaybes = Set.fromList . catMaybes

这只需要遍历列表一次,因为Set.fromList是一个很好的消费者。