Background
Many functions in Elm that work with List
s work equally well with empty and nonempty lists, for example:

List.sum
returns 0 for an empty list 
List.map
returns an empty list if given an empty list 
Html.div
does what you’d expect if given empty lists for attributes and/or children
However, other functions only really make sense for nonempty lists, and have a couple main ways of expressing/dealing with that:
 Return a
Maybe
:List.maximum
has the signatureList comparable > Maybe comparable
, returningNothing
for an empty list  Require an explicit ‘first item’ argument:
Random.uniform
has the signaturea > List a > Generator a
, forcing you to call it asRandom.uniform x [ y, z ]
instead ofRandom.uniform [ x, y, z ]
Either one of these could have been written the other way:

List.maximum
could have had the signaturecomparable > List comparable > comparable

Random.uniform
could have had the signatureList a > Maybe (Generator a)
Approach (1) is a bit simpler at first glance, but forces you to deal with a Maybe
even if you can guarantee the list is nonempty. Approach (2) looks a bit weird, and doesn’t handle the empty list case at all, but lets you avoid the Maybe
. (There’s also the third approach of using a dedicated nonempty list type like mgold/elmnonemptylist
, but I wanted to see how much could be done without requiring a separate type.)
Proposal
It occurred to me that we might be able to get the best of both worlds by adding (perhaps in the listextra
package) a function
ifNonEmpty : (a > List a > b) > List a > Maybe b
ifNonEmpty function list =
case list of
first :: rest >
Just (function first rest)
[] >
Nothing
and then following a convention of using approach (2) instead of (1) anywhere that we write a function that requires a nonempty list. We could then write code like
import List.Extra as List
List.maximum 2 [ 1, 3 ]
> 3
 Read as "if the list is nonempty, returns its maximum"
List.ifNonEmpty List.maximum [ 2, 1, 3 ]
> Just 3
List.ifNonEmpty List.maximum []
> Nothing
[ 2, 1, 3 ]
> List.filter (\n > n < 3)
> List.ifNonEmpty List.maximum
> Just 2
[ 2, 1, 3 ]
> List.filter (\n > n > 3)
> List.ifNonEmpty List.maximum
> Maybe.withDefault 1
> 1
which to me seems like a pretty nice way to handle both possiblyempty and guaranteednonempty lists of values.
Thoughts?
What do you think? Are there places where this breaks down or becomes awkward? If people like the idea, then I’d be happy to make a PR to listextra
, and start updating my own packages to use form (2). (This whole train of thought was kicked off when trying to come up with a nice solution to this elmgeometry
issue).