 <p>A very useful operator here is <code>&lt;|&gt;</code> from the <code>Alternative</code> class in <code>Control.Applicative</code>. For <code>Maybe</code>, it works like this:</p> <pre><code>Just a &lt;|&gt; _ = Just a Nothing &lt;|&gt; Just a = Just a Nothing &lt;|&gt; Nothing = Nothing </code></pre> <p>We can also take advantage of the fact that <code>x || x == x</code> is always true. This lets us write the following:</p> <pre><code>orMaybe a b = liftA2 (||) (a &lt;|&gt; b) (b &lt;|&gt; a) &lt;|&gt; Just False </code></pre> <p>If both <code>a</code> and <code>b</code> are <code>Just x</code>, the <code>liftA2 (||)</code> results in <code>Just (a || b)</code>. If one of them is <code>Nothing</code>, the <code>(a &lt;|&gt; b)</code> and <code>(b &lt;|&gt; a)</code> turn into either both <code>a</code> or both <code>b</code>, resulting in <code>Just (a || a)</code> or <code>Just (b || b)</code>. Finally, if both are <code>Nothing</code>, we get <code>liftA2 (||) Nothing Nothing</code> which leads to <code>Nothing</code>. The final <code>&lt;|&gt; Just False</code> then turns the whole expression into <code>Just False</code>.</p> <p>Now, I think this is a fun exercise to work through. But would I actually use this code? <strong>No</strong>! For <code>Maybe</code>, <code>Nothing</code> usually signifies failure and propagates; since you're using some very non-standard behavior, it's better to be explicit and pattern-match all the cases instead.</p> <p>Note: <code>liftA2</code> comes from <code>Control.Applicative</code>. It's just like <code>liftM</code> but for applicatives; I used it for consistency with <code>&lt;|&gt;</code>. You could have used <code>fmap</code> as well.</p>