Tengo tres funciones que encuentran el enésimo elemento de una lista:
nthElement :: [a] -> Int -> Maybe a
nthElement [] a = Nothing
nthElement (x:xs) a | a <= 0 = Nothing
| a == 1 = Just x
| a > 1 = nthElement xs (a-1)
nthElementIf :: [a] -> Int -> Maybe a
nthElementIf [] a = Nothing
nthElementIf (x:xs) a = if a <= 1
then if a <= 0
then Nothing
else Just x -- a == 1
else nthElementIf xs (a-1)
nthElementCases :: [a] -> Int -> Maybe a
nthElementCases [] a = Nothing
nthElementCases (x:xs) a = case a <= 0 of
True -> Nothing
False -> case a == 1 of
True -> Just x
False -> nthElementCases xs (a-1)
En mi opinión, la primera función es la mejor implementación porque es la más concisa. Pero, ¿hay algo en las otras dos implementaciones que las haga preferibles? Y, por extensión, ¿cómo elegiría entre usar guardias, declaraciones if-then-else y casos?
case compare a 1 of ...
case
declaraciones anidadas si utilizócase compare a 0 of LT -> ... | EQ -> ... | GT -> ...