I haven't done much roguelike development, but there's a couple of things I might be able to say based on my extremely limited Haskell experience:
Immutable data is your friend. At least, in Haskell it is (though, well, in Haskell you don't really have a choice). If your entire gameworld is built out of immutable data, it becomes easy to do things like save the game in a background thread, roll the game state back (for instance, you could store a reference to the game state at the beginning of a turn and, if something goes wrong that turn, pop up a warning, make the stored state the current one, and make a debugging save), allow simulating the gameworld forward, etc.. A Sands of Time-ish rewind mechanic is the easiest thing ever to implement if your gameworld is made of immutable data. And even if you didn't care for or intend to implement any of those features, it's still a great idea for architecture since it forces you to use proper functional design instead of leaving state lying around all over the place.
However, just as well in my limited experience, there's only so far you can go doing "proper functional design" in a roguelike engine. If it seems the code of many roguelike games is messy, the reason mightn't be so much that the programmers are bad than that roguelike games themselves are big weird messes of rules and exceptions and adjustments that look at and modify the game state in really arbitrary ways. So prepare to write a fair amount of code, and don't expect to be able to develop much of the engine's internals as modules with clean, coherent and uncoupled interfaces. You'll have to be made of sterner stuff than most designers to find those inside a roguelike.