| I have also initially struggled with structuring Haskell programs. Without knowing anything about what you want to do, here's my general approach: 1. Decide on an effect system Remember, Haskell is pure, so any side-effect will be strictly explicit. What broad capabilities do you want?
Usually, you need to access some program-level configuration (e.g. command-line options) and the ability to do IO (networking, reading/writing files, etc), so most people start with that. https://tech.fpcomplete.com/blog/2017/06/readert-design-patt... 2. Encode your business logic in functions (purely if possible) Your application does some processing of data. The details don't matter. Use pure functions as much as possible, and factor effectful computations (e.g. database accesses) out into their own functions. 3. Glue everything together in a monadic context Once you have all your business logic, glue everything together in a context with your effect system (usually a monad stack using ReaderT). This is usually where concurrency comes in (e.g. launch 1 thread per request). --- Beyond this, your application design will depend on your use-case. If you are interested, I strongly suggest to read 'Production Haskell' by Matt Parsons, which has many chapters on 'Haskell application structure'. |
This shouldn't even be proposed as a question to someone new to Haskell. They should learn how monad transformers work and just use them. 90% of developers playing around effect systems would be just fine with MTL or even just concrete transformers. All Haskell effect systems should be considered experimental at this point with unclear shelf lives.
Everything else you said I agree with as solid advice!