Haskell is one of the rare language/community where composability is the default. Even purely technically, few languages do composability as well as Haskell.
The Gang of Four pattern you mention most likely work around weaknesses of Java. As such, they demonstrate the shortcomings of Java, not it's strengths. If you need a pattern that badly, make it a language feature, dammit. (Even without Lisp-style macros, source-to-source transformation is quite viable.)
> But in my experience, the bigger part often has slightly different properties, behaviours, or uses which warrant a different type with more features.
I'd say most of the time, you just failed to capture the commonalities. More specifically, you seek generality through exhaustiveness, when you should use genericness instead.
If you stumble upon something that looks like a monoid, except for such and such detail, then the details probably need to be either removed (they're could be design bug), or integrated into a generic bucket or something.
> For example, […]
Those specs suck. Whoever asked you this don't understand their own needs, or are struggling with a legacy behemoth that should eventually be replaced. (EDIT: or, as mightybyte suggested, you just approached the problem the wrong way. Which strengthen my point about failing to see the commonalities.)