@popefucker@cybre.space monoids aren't so important, but monads are significant because they're what allows for composable code with "side effects"
typically, we want to be able to compose functions together:
h = f . g
because this makes designing programs easier.
but when it comes to functions that have side effects (like writing files or displaying stuff on the screen), we want those to be isolated from other functions, because the *order* in which we do things is suddenly important
@popefucker@cybre.space for functions with no side effects (those that just take something and return something) it doesn't matter what order we do them in.
but functions that ask the user questions and wait for responses? the order matters!
so we have to wrap up whatever our function does in a higher order type:
askAndResponse :: String -> IO (String)
let's say this function displays whatever string we pass to it to the user, then waits for user response...
@popefucker@cybre.space I don't know if that made sense?