Why are mutable data structures and other mutability represented using IO in functional languages? I'm looking at e.g. Haskell's IORef or Idris' IOArray.
I don't think I mean this as a historical or design question. I don't quite understand why IO is suitable for mutation - or rather, why mutation becomes pure when encapsulated in IO.
You don't need to represent them with
IO. It's possible to do them inSTinstead. But you can obviously represent them withIO, where any dirty side effect can be achieved. So if you're working inIOanyway, it's easiest to just do the mutations there too, this way you don't need to put any worry on welding different monads together. If you're not already working inIO, you should useSThowever.