# Removal candidates in patterns

Duncan Coutts duncan.coutts at worc.ox.ac.uk
Thu Jan 26 15:15:58 EST 2006

```On Thu, 2006-01-26 at 19:35 +0000, Olaf Chitil wrote:
> As response to both Aaron and Duncan,
>
> >foo 0 = ...
> >foo n = ...
> >
> >
> And what about the negative numbers? For negative numbers the second
> equation matches, which in 90% of all cases in practise has never been
> written for them. Aaron's Ackerman function disappears in infinite
> recursion... Besides, what is ack 0.5 0.5?

Isn't the same true for:

foo n | n == 0    = ...
| otherwise = ...

It's still going to fail for negative numbers.

> The use of n+k patterns, but also the definition pattern above wrongly
> lead programmers to believe that they are dealing with natural numbers.
> There is no nice primitive recursion for integers. Even worse, without a
> type signature restricting its type, foo will be defined for all numeric
> types. For Float or Rational it makes hardly any sense.

The above example is still defined for all numeric types.

Eliminating that syntax form doesn't remove those problems.

> If Haskell had a type for natural numbers I'd be in favour of n+k and k
> patterns (working only for this type, not any other numerical type).

I'm in favour of removing n+k patterns too.

> Using primitive recursion on integers or even arbitrary numbers is
> misleading. You can teach primitive recursion nicely for algebraic data
> types, because the recursive pattern of the function definition follows
> the recursive pattern of the type definition.

Char is a type that is not constructed recursively and yet no one seems
to have problems with character literals as constructors and thus as
patterns. Each character literal is a Char constructor. Why can't each
numeric literal be a constructor for the numeric types?

I think it's a perfectly reasonable mental model for people to believe
that:
data Char = 'a' | 'b' | 'c' | ...
data Int  = ... -2 | -1 | 0 | 1 | 2 | ...

I don't see why we should remove one and not the other. Students will
ask why the can pattern match on strings, characters and booleans but
not numbers.

Perhaps primitive recursion on integers is misleading, but people will
still write

foo n | n == 0    = ...
| otherwise = ...

where they previously wrote

foo 0 = ...
foo n = ...

so what have we gained except less notational convenience?

Not all pattern matching on numeric literals is involved with recursion
on integers, where as virtually all n+k patterns is used for that
purpose. So there is some distinction between the two forms. n+k
patterns are a quirk of the numeric types. k patterns are regular with
other types in the language.

> With respect to tools of which Hat is one example: If it is hard to
> build tools, then less tools will be built. Compare the number of tools
> for Scheme with those for Haskell. Most tools grow out of student
> projects  or research projects;  these have  rather limited resources.

It's partly the complexity of the language and partly because our latest
language spec (H98) is not the language that we all use (H98 + various
extensions). I'm sure Haskell-prime will help in this area.

I don't mean to belittle the difficulty of building tools. I know how
hard it is, I'm trying to build one too.

Duncan

```