Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Design of data types in Haskell

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?

like image 203
L01man Avatar asked Jan 17 '23 07:01

L01man


1 Answers

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?

like image 173
mergeconflict Avatar answered Jan 25 '23 05:01

mergeconflict