Question

I find myself writing this:

and_then :: x -> Maybe [x] -> Maybe [x]
x `and_then` mxs = do
  xs <- mxs
  return (x:xs)

Is there some simpler way to achieve the same thing?

Basically this is your standard recursive loop that processes a list - except that processing can fail (which is different from the result merely being an empty list). That means that where I would normally write

z : process xs ys

I now have to write

z `and_then` process xs ys

Since this is a rather common idiom, I was wondering whether some pre-existing function could help me out. (Several Hoogle searches fail to find any functions with types similar to the above.)

Was it helpful?

Solution

Since your do notation is only invoking the Maybe layer we might think about the (:) operation as being independent of the Maybe's effect—it's just yet another function being passed to the value wrapped in Maybe. That leads us to generalize the code a bit

foo :: (x -> b -> b) -> x -> Maybe b -> Maybe b
foo f x m = do
  b <- m
  return (f x b)

This makes it much more clear that we're just dealing with an fmap

fmap fx m = do b <- m
               return (fx b)

So perhaps the most standard way of writing your desired function is

(z:) <$> process xs ys
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top