1

Is it better to do:

charToAction 'q' = Just $ WalkRight False
charToAction 'd' = Just $ WalkRight True
charToAction 'z' = Just Jump
charToAction _ = Nothing

or

charToAction x = case x of
    'q' -> Just $ WalkRight False
    'd' -> Just $ WalkRight True
    'z' -> Just Jump
    _ -> Nothing

?

3
  • Which one do you like better? There's no performance difference in either of these solutions. Just go with the one you personally like better in terms of syntax. Commented Jun 24, 2012 at 16:29
  • if, case, guards, pattern-matching, I'm torn apart by these! Commented Jun 24, 2012 at 16:52
  • if and guards aren't good options for this, but the two you're asking about are indeed equivalent – as a matter of fact, GHC will pack different patterns for a function in a case statement in the first compilation step anyway. Commented Jun 24, 2012 at 17:43

3 Answers 3

8

There's absolutely no functional difference whatsoever. It's a matter of personal preference.

Sign up to request clarification or add additional context in comments.

1 Comment

There is a alight difference when you have multiple arguments with regards to the willingness to back up and retry, but you can always desugar to the case statements, since that is what happens in ghc core. ;)
2

There is no performance difference because the first definition desugars to the second. You were right to prefer a case + pattern matching solution to one with guards and an equality test, some excellent general remarks are here: http://existentialtype.wordpress.com/2011/03/15/boolean-blindness/ (His examples are in ML but translate immediately to Haskell).

Note that you are misusing otherwise in the second definition; you should just write _ -> Nothing It isn't the otherwise of guards that you are using, you could as well have written fmap -> Nothing and the same would have happened.

1 Comment

Thanks for the article! It's true booleans are very low-level and thus should be avoided when possible.
1

As others mentioned, there is no difference in the generated code as the former approach desugars to the latter approach, however I can point out some other considerations that may help you choose one or the other to use:

  1. The former approach looks prettier in some circumstances (although I personally think that once you have lots of cases it is distracting)
  2. The former approach makes it slightly more difficult to refactor the name. Using the case statement the name of the function only appears once.
  3. Case statements can be used anywhere in your code and can be used anonymously. The former approach requires using a let or where block to define pattern-matching functions within a function.

However, there are no cases where you can't translate one into the other. It's entirely a matter of coding style.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.