你将如何为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]
答案 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
是一个很好的消费者。