
On 6 Feb 2008, at 5:17 PM, Jeff φ wrote:
IO(U)Arrays are only one variant of mutable Array, there are also ST (U)Arrays, which are often preferred.
I should have worded my question better. The MArray interface is implemented in both the ST and IO monad. A state monad seems like a logical place for mutable arrays. However, I don't understand the motivation for implementing it in IO. Were mutable arrays added to IO because it would be difficult to write code that does both IO and manipulates arrays otherwise?
Yes. As I understand it, the reasons are roughly as follows: (a) The ST monad is a fairly clever hack, and is some years (4 or 5?) younger than IO. (b) You can't have an ST-mutable array as a global variable, but you can do this with IO. It's ugly, but some libraries are rumored to require it (see the discussion in http://haskell.org/haskellwiki/ Top_level_mutable_state). (c) In particular, libraries that need to do I/O and/or FFI are rumored to be particularly in need of top-level mutable state, so it's natural to combine the two (or three). (d) It's very difficult to combine monads. Clean's uniqueness types / can/ be combined (as could arbitrary state monads). In general, IMHO what you normally want when combining monads is their coproduct. A general coproduct is quite ugly, but it simplifies nicely in particular cases. Clean, by restricting the problem to combining uniqueness-type-based state monads, can combine monads more easily than Haskell can in the general case. 15 years ago, when these decisions were made, it seemed easier to have a single monad. (e) To a certain extent, IO is the monad in Haskell for `everything other languages can do that we can't'. That's just the nature of the beast; the name IO is simply taken from the most prominent example. So IO's mandate is to do everything C can do better. (f) Some of use consider the IO monad (and mutable arrays in general) deprecated for precisely this reason; the rest seem to want C with a nicer syntax. They use IO, we try to avoid it entirely. jcc