UPenn Homework 3: localMaxima :: [Integer] -> [Integer]
The implementation can be much simpler.  The main insight I can offer is to use map and filter instead of Maybe and writing your own accumulate.  In addition,


Instead of writing case l2 of …, use pattern matching.
Look for library functions that you can take advantage of.  (Here, I've used tails from Data.List.)
In keeping with the "wholemeal programming" goal, use higher-order functions instead of recursion.
Higher-order functions also let you use point-free style, which lowers your mini-golf score.


I suggest using where instead of let … in … because the former encourages top-down strategic thinking.  You want to write a "one-liner", and add supporting details only if necessary.

import Data.List (tails)

localMaxima :: [Integer] -&gt; [Integer]
localMaxima = map (!!1) . filter isLocalMax . tails
  where
    isLocalMax (a:b:c:_) = a &lt; b &amp;&amp; b &gt; c
    isLocalMax _         = False


In addition to being shorter, this implementation is more maintainable.  You can tell at a glance what map (!!1) . filter isLocalMax . tails does, but reverse (accumulate l []) is mysterious.  Furthermore, because isLocalMax is not intertwined with accumulate, you can trace the execution by inspecting tails xs, then (filter isLocalMax . tails) xs, etc.