The simplest definition of liftMaybe
would be
import Data.Traversable (sequenceA)
liftMaybe :: (a, Maybe b) -> Maybe (a, b)
liftMaybe = sequenceA
The documentation for sequenceA
can be found here http://hackage.haskell.org/package/base/docs/Data-Traversable.html.
The general type signature is sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
, but in this case t
is (,) c
and f
is Maybe
.
Also, partialgraph
could be expressed with traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)
(which is also from Data.Traversable
):
partialgraph :: (a -> Maybe b) -> [a] -> [(a, b)]
partialgraph f = mapMaybe $ \x -> traverse f (x, x)
or, if you prefer a little more pointlessness:
partialgraph f = mapMaybe (traverse f . join (,))
EDIT: When I wrote this answer, I didn't realize that the required Traversable
and Foldable
instances aren't defined in the GHC 7.6.3 standard library (they are in GHC 7.8 though). Here they are, courtesy of @robx:
instance Foldable ((,) a) where
foldr f y (u, x) = f x y
instance Traversable ((,) a) where
traverse f (u, x) = (,) u <$> f x