I have yet to have my big ah-ha moment for how to do what I do (scientific computing) in Haskell.
I recently found myself needing a proof-of-concept implementation for solving a bunch of big tridiagonal matrices in parallel using MPI. I thought to myself "here's an opportunity to use Haskell!", but I must confess I'm rather stumped for how one goes about allocating some memory, banging on it, communicating a subset of it to another processor(s), reading a buffer from the other processor, and then banging on the memory I allocated before some more based on what I got back from the other processors(s).
Does one actually attempt to control the machine with this level of granularity with Haskell? Can one actually get any mileage out of the type system doing this sort of thing? Or am I just trying to fit a square peg in a round hole?
In my experience, Haskell is not yet a great language for numerically intensive computing.
I'll explain in a bit, but before I do, let me first address your question about "can I bang on bits?". Yes, you can allocate memory and do all the low-level hacking you please in Haskell. It's not really any harder than in C, although the notation is different and that throws people. But because this is a very imperative way of programming, it's also not going to be any faster than C (typically it'll be a bit slower).
There are even MPI bindings for Haskell, and they look pretty much the same as for other languages (i.e. very low level).
If you're just foontling around imperatively in big homogeneous arrays and sending messages, then the type system really won't do you any good, and you'll rightly find yourself wishing for the notational convenience and speed of Fortran 95.
You could use immutable arrays (the Vector type is your friend) and higher order functions instead, and thereby benefit from Haskell's rather nice parallel evaluation support with only a little effort. This is quite practical, and can lead to pretty code that runs quickly.
Where all the fancy type-related machinery comes into play for numeric code is still largely a matter of research. There are interesting projects underway for parallel programming (both on CPUs and GPUs) that rely heavily on the type system. They're not obviously useful for real work yet, and since they rely on advanced type system features, neither are they something you just pick up and use as a newbie. Nevertheless, I think they're pretty cool projects, and I have been watching them for a few years.
So while there's a lot of interesting stuff going on, the current state of affairs is somewhat mixed. You might enjoy learning your way through it, though; there are many rewards to the path.
Unfortunately, repa and vector are sometimes a few times slower than counterparts in C or C++ for the lack of SIMD intrinsics. Thankfully, things are moving forward fast on that front:
repa also has some unfortunate lacunae, either in the API or in the documentation.
For instance, one thing I tried to do but couldn't - apply `scanl` to an array with a piece of intermediate state that is threaded through the computation, save the piece of state at the end, and then apply `scanr` to the same array, using the piece of state from the application of `scanl`.
the key bit is not yet! :)
You're highlighting all the right points, and i'm actually spending some time this summer putting the pieces together for a better numerical story with some really cool use cases and aiming for an out of the box turn key experience with numerical algorithm awesomeness.
I think once the pieces are laid out nice and clear, a dramatically better numerical toolchain will be born.
:)
I recently found myself needing a proof-of-concept implementation for solving a bunch of big tridiagonal matrices in parallel using MPI. I thought to myself "here's an opportunity to use Haskell!", but I must confess I'm rather stumped for how one goes about allocating some memory, banging on it, communicating a subset of it to another processor(s), reading a buffer from the other processor, and then banging on the memory I allocated before some more based on what I got back from the other processors(s).
Does one actually attempt to control the machine with this level of granularity with Haskell? Can one actually get any mileage out of the type system doing this sort of thing? Or am I just trying to fit a square peg in a round hole?