This member of DarcsCommand has some issues. 23 commands set this member
to -1, which means 'no check for number of extra args, please'. Changing
the type to Maybe Int would be more idiomatic but that is beside the
point. A fixed number of (normal i.e. non-option) arguments is something
of a special case. This is the histogram of all existing values for
That is, almost half the commands take no extra args, almost half again
disable the check (presumably because the number of arguments is variable).
Furthermore, the error message produced when the expectations set by
commandExtraArgs is not met is often less useful than it could be. For
example, I just removed the check for the push command and replaced it
with an explicit error message in the command, because I find that
Cannot push to more than one repo
is the more useful than the generic
Bad argument: repo1 repo2
I thought about changing the type from Int to Int -> Bool, so that
commands can plug in an arbitrary predicate, such as (>=2) if they
accept 2 or more arguments. But then we need to also pass in an
appropriate error message to be issued if the criterion is not met, so
the type would rather be something like String -> Int -> Bool. Even that
may not be flexible enough.
That begs the question: why not instead do this check completely inside
the commands? If it turns out that this means we repeat ourselves, then,
well, factor common stuff into library functions.
I have found on more than one occasion that this pattern (which is
nothing more than, you name it, functional programming) is superior to
the approach taken by the current command implementation infrastructure
(which is, more or less, object-oriented).
BTW, I have just seen that there is also commandExtraArgHelp. Perhaps we
just need a small combinator library for specifying extra arguments...