4

Which do you suggest:

data Direction = Left | Right
type Direction = Bool
newtype Direction = Direction Bool

Then I'm making:

data Move = WalkRight Bool | Jump

or

data Move = Walk Direction | Jump

depending of the previous answer. I have a function of type Char -> Maybe Move:

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

Should I change my type Move into:

data Move = Stationary | WalkRight Bool | Jump

? The function would become:

charToAction 'q' = WalkRight False
charToAction 'd' = WalkRight True
charToAction 'z' = Jump
charToAction _ = Stationary

I wonder this because the list doesn't need a Maybe:

data [a] = [] | a : [a]

Or is there a way to derive Maybe to make it cleaner?

3
  • WalkRight False isn't very suggestive of its intended meaning. Commented Jun 24, 2012 at 16:53
  • You're right. Which definition of Direction should I keep? Commented Jun 24, 2012 at 16:57
  • 1
    n.b. data [a] = [] | a : [a], unlike what you've written. Commented Jun 24, 2012 at 21:44

1 Answer 1

9

I prefer something like:

data Direction = Left | Right
data Move = Walk Direction | Jump
type Action = Maybe Move
type ActionList = [Action]

charToAction :: Char -> Action
charToAction c = case c of
  'q' -> Just $ Walk Left
  'd' -> Just $ Walk Right
  'z' -> Just $ Jump
  _   -> Nothing

stringToActions :: String -> ActionList
stringToActions = map charToAction

under the principle that each data type clearly explains its own purpose, and doesn't "assume" anything about how it might be used. Some counter-examples:

newtype Direction = Direction Bool
data Move = Stationary | Walk Direction | Jump

Here, Direction doesn't really explain what it means... does it mean you have a direction or you don't have a direction? Hmmm! Also, what happens when you need Up and Down? It's hard to extend your program if Direction is just a Bool.

And Move has a data constructor Stationary here that isn't actually a move at all. You "leak" the notion that some keystrokes won't result in a move. Again that will end up complicating your code.

Make sense?

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

6 Comments

Thanks. Are type Action = Maybe Move and type ActionList = [Action] a good habit? As for stringToActions (fun idea, BTW), it's just a curry, so is it worthy to define? And Move has a data constructor Stationary here that isn't actually a move at all.. Well, lists are the same, [] is not really a list :P. And 0 is not really a quantity... For Walk, I don't need Up or Down to be part of Direction, so I'll rename the type DirectionX.
Well, it all depends :) For Stationary, yeah, there might be other things (aside from char mapping) for which a Stationary move might also make sense. If you're making some kind of platform game, perhaps you could define data Action = Move Move | Shoot Direction | Duck | Nothing... Who knows! The most important thing is to model the data separately from the operations involving it.
Yes, type constructors and other functions :).
I'm not sure ActionList is a good type to make. Really, it says nothing more than [Action], which, after all, literally means "list of Actions"! In this case, [Action] is also easier to read. Now, if you had a type with a more specific role than just a list of actions, like a list of possible actions to take, then I definitely see the case for something like type ActionChoices = [Action]. A type synonym is only good for providing additional information to the programmer, which "ActionList" does not do.
By similar reasoning to Tikhon Jelvis, I don't think type Action = Maybe Move is a good type synonym either. I'd just use Maybe Move directly, since Maybe is such a common type that has so many utility functions for it. Having the [Maybe Move] directly in the type signatures makes it easier for readers of the code to know what they can do with values of that type.
|

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.