About Haskell
Advantages of Haskell for Maths
A few things about Haskell that make it particularly nice for maths:
- Arbitrary precision integer arithmetic is built in
- "List comprehensions" allow us to write code which is close to the usual mathematical notation for sets, for example:
factors n = [d | d <- [1..n], n `mod` d == 0]. - Lazy evaluation means that (with care) we can work with infinite lists. See the Dirichlet series and p-adic numbers code for examples.
- Haskell can run interactively, so that we can simply type in Haskell expressions and have them evaluated. This, together with language features which enable user-defined data structures to be treated like built-in ones (for example in the way that they are parsed and displayed), means that we usually don't need to bother writing a "front-end" for our maths code.
But the main thing is that it is much quicker to write code in Haskell than in an imperative language like C++. See for example this study - in which expert Haskell, Ada and C++ programmers were asked to tackle the same programming task - the Haskell code came out about 10 times shorter than the Ada / C++ code, and took significantly less time to develop.
For experimental maths programming, I tend to write the code, run it a few times, then move onto something else. So speed of development is far more important than speed of execution. (However, I don't want to give the impression that Haskell is slow - it isn't.)
Where to get Haskell
The Haskell website is at http://www.haskell.org/. There are two very good Haskell development environments - Hugs and GHC - both of which are free. I tend to use Hugs for development, and GHC if I need speed. Hugs is interpreted, GHC includes both a compiler and an interpreter. Both these packages can build executable files, but I find it much easier to work in the interactive environment.
What I would change about Haskell
Nothing's perfect, and that includes Haskell. There are two main things I would change about Haskell:
- I would allow polymorphism over an enumeration. Suppose, for example, that we want a class which represents finite fields of prime order. Then what we would really like is to be able to declare a variable to have type "FF 5", say. Then, if we tried to add this to another variable of type FF 7, the type checker would spot our mistake. As it is (see the finite fields code), we have to spot this type of mistake at run time.
- I would sort out the maths classes in the Prelude. They clearly weren't written by a mathematician. Consider for example, that if you want to say that a type is a ring, with operations +, *, -, then the Prelude thinks that you should also provide implementations of abs and signum, which of course only make sense for rings that can be embedded in the real (or complex) numbers. The main problem with the maths classes in the Prelude is that they don't separate arithmetical concepts (such as +, *, -), from geometrical concepts (such as abs, which is a measure of size).