Confused about custom data types in Haskell

haskell, types

Solution

You need a `Show` instance to convert the type to a printable representation (a `String`). The easiest way to obtain one is to add

deriving Show

to the type definition.

data Person = Person { 
    first_name :: String, 
    last_name :: String,   
    age :: Int }
      deriving (Eq, Ord, Show)

to get the most often needed instances.

If you want a different `Ord` instance, as suggested in the comments, instead of deriving that (keep deriving `Eq` and `Show` unless you want different behaviour for those), provide an instance like

instance Ord Person where
    compare p1 p2 = case compare (age p1) (age p2) of
                      EQ -> case compare (last_name p1) (last_name p2) of
                              EQ -> compare (first_name p1) (first_name p2)
                              other -> other
                      unequal -> unequal

or use pattern matching in the definition of `compare` if you prefer,

    compare (Person first1 last1 age1) (Person first2 last2 age2) =
        case compare age1 age2 of
          EQ -> case compare last1 last2 of
                  EQ -> compare first1 first2
                  other -> other
          unequal -> unequal

That compares according to age first, then last name, and finally, if needed, first name.

Problem

The task: I am trying to create a custom data type and have it able to print to the console. I also want to be able to sort it using Haskell's natural ordering. The issue: Write now, I can't get this code to compile. It throws the following error: `No instance for (Show Person) arising from a use of 'print'`. What I have so far: ``` -- Omitted working selection-sort function selection_sort_ord :: (Ord a) => [a] -> [a] selection_sort_ord xs = selection_sort (<) xs data Person = Person { first_name :: String, last_name :: String, age :: Int } main :: IO () main = print $ print_person (Person "Paul" "Bouchon" 21) ```

Original source