title: Why is `Eq a` constraint required for the solution using `elem`?
body: <p>I was solving the following exercise from the <a href="http://haskellbook.com/" rel="noreferrer">Haskell Book</a>:</p>
  
  <pre><code>-- &gt;&gt;&gt; flipMaybe [Just 1, Just 2, Just 3]
  -- Just [1, 2, 3]
  -- &gt;&gt;&gt; flipMaybe [Just 1, Nothing, Just 3]
  -- Nothing
  
  flipMaybe :: [Maybe a] -&gt; Maybe [a]
  flipMaybe = undefined
  </code></pre>
  
  <p>First I tried using <code>elem</code>,</p>
  
  <pre><code>flipMaybeWithElem :: [Maybe a] -&gt; Maybe [a]
  flipMaybeWithElem ms
    | Nothing `elem` ms = Nothing
    | otherwise         = Just (catMaybes ms)
  </code></pre>
  
  <p>but I got the error message:</p>
  
  <pre><code>misc.hs:86:5: error:
      • No instance for (Eq a) arising from a use of ‘elem’
        Possible fix:
          add (Eq a) to the context of
            the type signature for:
              flipMaybe2 :: forall a. [Maybe a] -&gt; Maybe [a]
      • In the expression: Nothing `elem` ms
        In a stmt of a pattern guard for
                       an equation for ‘flipMaybe2’:
          Nothing `elem` ms
        In an equation for ‘flipMaybe2’:
            flipMaybe2 ms
              | Nothing `elem` ms = Nothing
              | otherwise = Just (catMaybes ms)
     |
  86 |   | Nothing `elem` ms = Nothing
     |     ^^^^^^^^^^^^^^^^^
  </code></pre>
  
  <p>I understand that I should just add the <code>Eq a =&gt;</code> constraint to the function signature, but I was trying to stay true to the provided function stub. So I reused previous functions, and it did work:</p>
  
  <pre><code>flipMaybe :: [Maybe a] -&gt; Maybe [a]
  flipMaybe ms =
    case (filter isNothing ms) of
      [] -&gt; Just (catMaybes ms)
      _  -&gt; Nothing
  </code></pre>
  
  <p>The helper functions used:</p>
  
  <pre><code>isNothing :: Maybe a -&gt; Bool
  isNothing Nothing = True
  isNothing _       = False
  
  mayybee :: b -&gt; (a -&gt; b) -&gt; Maybe a -&gt; b
  mayybee b _ Nothing = b
  mayybee b f (Just a) = f a
  
  fromMaybe :: a -&gt; Maybe a -&gt; a
  fromMaybe a maybe = mayybee a id maybe
  
  catMaybes :: [Maybe a] -&gt; [a]
  catMaybes xs = map (fromMaybe undefined) (filter isJust xs)
  </code></pre>
  
  <hr>
  
  <p>So <strong>why doesn't the first solution with <code>elem</code> work without the type constraints?</strong></p>
  
  <p>Is it simply because <code>filter</code> and <code>isNothing</code> have no constraints on the type variables and <code>elem</code> has? (Also with <code>isNothing</code> the type variable never even comes into play because it is ignored.)</p>
  
  <pre><code>&gt; :t filter               
  filter :: (a -&gt; Bool) -&gt; [a] -&gt; [a]
  
  &gt; :t isNothing                              
  isNothing :: Maybe a -&gt; Bool                               
  
  &gt; :t elem
  elem :: (Eq a, Foldable t) =&gt; a -&gt; t a -&gt; Bool 
  </code></pre>
  
  <p><code>Maybe</code> has an <code>Eq</code> instance, but I guess the compiler does not know anything about <code>a</code>, right?</p>