Thanks Viktor, you've answered (in the negative) one of my follow-on q's which was:
isn't the comma just standing for Boolean `&&` ?
> which would otherwise be something like: ...
I would go:
> smtpGreeting :: Int -> SmtpReply -> SmtpM B.ByteString
> smtpGreeting _ r =
> | replyCont r = pure B.empty> | code `div` 100 /= 2 = B.empty <$ modify' bail code
> | otherwise = smtpSendHello
> where
> code = replyCode r
> bail code s =
> s { smtpErr = ProtoErr code $ replyText r }
> but I find the pattern guard form to read "declarative",
Hmm? Your `code <- ...` left-arrow doesn't look at all declarative to me. It's reminiscent of a binding in a do-block, or a 'source' in a comprehension. Strong imperative/sequential overtones.
> with less "if then else" baggage and nesting getting in the way of seeing the essential conditions.
My suggestion above also avoids "if then else".
I guess a case of de gustibus ...
To my taste, GHC Haskell is just too bloated/there's too many (equivalent) ways of writing code/there's too many idioms I have to keep up with to read code. It's not that there's anything particularly 'wrong' with any one of them; it's the sheer number of them. I'd have to say patterns/matching suffer a low power to weight ratio, where 'weight' means syntactic clutter and gotcha's: View pattern arrow-from-nowhere, I'm looking at you; pattern signatures double-forall's, empty forall's, double-constraints, I'm looking at you.