Jump to content
  • Advertisement
Sign in to follow this  
dmatter

Haskell - Guards or if-then-else?

This topic is 3705 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Is one of these considered more idiomatic than the other?:
-- With guards
func a
  | pred a = Just a      -- some comment here
  | otherwise = Nothing


-- With if-then-else (just one possible arrangement)
func a = if pred a
         then Just a     -- some comment here
         else Nothing
I'm never really sure which to prefer. I like the former myself but I'd rather code in a way that's best for the majority of potential readers.

Share this post


Link to post
Share on other sites
Advertisement
The former is idiomatic. if/then/else is a much less common construction in languages with algebraic types and pattern matching than it is in languages without them.

Share this post


Link to post
Share on other sites
Thank you, I'm quite pleased to hear that actually.

I've just submitted my first ever Haskell program as my functional programming assignment. I might post the code later for critiquing as I'm doubtful I'll get feedback on it before my second assignment is due. I'll probably start a new thread for that.

Share this post


Link to post
Share on other sites
In erlang you would use case:

a(X) ->
case X of
X -> true; // matches X returns "true"
_ -> nothing // matches anything else, returns "nothing"
end.

What's the point of an erlang guard?

a(X,Y) ->
if
X>Y -> X; // the guard checks for an eval of "true" returns X
Y>X -> Y; // the guard checks for an eval of "true" returns Y
true -> nothing // the atom "true" always evals to "true" returns "nothing"
end.

Share this post


Link to post
Share on other sites
If this function is very general-purpose, you might want to generalize its type a bit:


import Control.Monad

returnWhen :: MonadPlus m => Bool -> t -> m t
returnWhen cond val = guard cond >> return val

func a = returnWhen (pred a) a


This works in the Maybe monad (returns Just a or Nothing), the List monad (returns [a] or []), the IO monad (returns a or throws an exception), etc.

Share this post


Link to post
Share on other sites
When there are guards available, use them.

Quote:
In erlang you would use case:

a(X) ->
case X of
X -> true; // matches X returns "true"
_ -> nothing // matches anything else, returns "nothing"
end.

No.

You either

a) don't know erlang from your elbow or

b) are posting nonsense on purpose for some reason.

That code returns true in all cases: it is equivalent to the function


a(_) -> true.


as a bound variable will always match itself. Any self-respecting erlang compiler will warn you of this, too: it's so nonsensical even the compiler can catch it!

Not to mention that double slashes are not valid erlang comment delimiters.

Lastly, it has nothing to do with guards.

In erlang, you would use guards if your predicate is a built-in function or an operator (this is because the compiler needs to guarantee termination and side-effect freedom of pattern expressions, which guards are) or you'd use case if your predicate was defined by yourself.

For example, if your predicate is the builtin function is_integer, you'd write your function like so:


a(X) when is_integer(X) ->
{just, X};

a(_) ->
nothing.


and if it's a predicate defined by yourself (thus the compiler can't establish its side-effect freedom and termination) you might write it like this:


b(X) ->
case pred(X) of
true ->
{just, X};
_ ->
nothing
end.


Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!