What is the best practice in Haskell for defining constants in data properties?

Viewed 89

Take for example the code below..I've defined some shoes that are wearables with specific properties... (Nike, Adidas, Puma)

data Shoe = Nike | Adidas | Puma deriving Show

class Wearable a where
    forFeet :: a -> Bool
    forUpperBody :: a -> Bool
    comfortLevel :: a -> Int
    purchasePrice :: a -> Int
    from :: a -> String


instance Wearable Shoe where
    forFeet _ = True
    forUpperBody _ = False
    comfortLevel Nike = 5
    comfortLevel Adidas = 3
    comfortLevel Puma = 8
    purchasePrice Nike = 5
    purchasePrice Adidas = 3
    purchasePrice Puma = 3
    from _ = "The World Store"

Defining attributes such as purchasePrice, and comfortLevel on the different shoes within the instance of the typeclass feels a bit clunky here.. What is the best practice for this type of behavior in defining attributes of certain types?

1 Answers

I would say use a record instead of a class in this case:

data Shoe = Nike | Adidas | Puma deriving Show

data Wearable = Wearable
    { forFeet       :: Bool
    , forUpperBody  :: Bool
    , comfortLevel  :: Int
    , purchasePrice :: Int
    , from          :: String
    }

mkShoe :: Int -> Int -> Wearable
mkShoe comfort price = Wearable
    { forFeet       = True
    , forUpperBody  = False
    , comfortLevel  = comfort
    , purchasePrice = price
    , from          = "The World Store"
    }

nike, adidas, puma :: Wearable
nike   = mkShoe 5 5
adidas = mkShoe 3 3
puma   = mkShoe 8 3

getWearable :: Shoe -> Wearable
getWearable show = case shoe of
    Nike   -> nike
    Adidas -> adidas
    Puma   -> puma
Related