From a technical point of view, all three versions are equivalent.
As the saying goes, my rule for styles is that if you can read it as if it were English (read | as "when", | otherwise as "otherwise" and = as "is", or "be "), you are probably doing something right.
if..then..else is when you have one binary condition or one decision that you need to make. Nested if..then..else expressions are very rare in Haskell, and guards should be used almost always.
let absOfN = if n < 0 -- Single binary expression then -n else n
Each if..then..else expression can be replaced with a guard if it is at the top level of the function, and this should usually be preferred, since you can add more cases more easily:
abs n | n < 0 = -n | otherwise = n
case..of is when you have several code paths, and each code path is controlled by a value structure, that is, by way of pattern matching. You are very rare on True and False .
case mapping of Constant v -> const v Function f -> map f
The guards complement case..of expressions, which means that if you need to make complex decisions depending on the value, first make decisions depending on the structure of your input, and then make decisions about the values ββin the structure.
handle ExitSuccess = return () handle (ExitFailure code) | code < 0 = putStrLn . ("internal error " ++) . show . abs $ code | otherwise = putStrLn . ("user error " ++) . show $ code
BTW. As a hint, always create a new line after = or before | if the material after = / | too long for one line, or uses more lines for another reason:
dflemstr Feb 19 2018-12-12T00: 00Z
source share