{-# LANGUAGE RankNTypes, ScopedTypeVariables #-} module Data.Set.ExtraG ( gFind ) where import Data.Generics hiding (GT) import Control.Monad.Reader import Data.Set (Set, fromList) gFind :: forall a b. (Data a, Typeable b, Ord b) => a -> Set b gFind x = fromList (gFind' x :: [b]) -- | @gFind a@ will extract any elements of type @b@ from -- @a@'s structure in accordance with the MonadPlus -- instance, e.g. Maybe Foo will return the first Foo -- found while [Foo] will return the list of Foos found. gFind' :: (MonadPlus m, Data a, Typeable b) => a -> m b gFind' = msum . map return . listify (const True)