2012-04-11 20 views
6

La tarea: Estoy tratando de crear un tipo de datos personalizado y poder imprimir en la consola. También quiero poder ordenarlo usando el orden natural de Haskell.Confundido sobre tipos de datos personalizados en Haskell

El problema: Escribir ahora, No puedo obtener este código para compilar. Se arroja el siguiente error: No instance for (Show Person) arising from a use of 'print'.

Lo que tengo hasta ahora:

-- 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) 

Respuesta

8

Necesita un ejemplo Show para convertir el tipo de una representación imprimible (un String). La forma más fácil de obtener uno es agregar

deriving Show 

a la definición de tipo.

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

para obtener las instancias necesarias con más frecuencia.

Si quieres un Ord instancia diferente, como se sugiere en los comentarios, en lugar de derivar de que (mantener derivar Eq y Show a menos que desee un comportamiento diferente para aquellos), proporcionan una instancia como

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 

o uso la coincidencia de patrones en la definición de compare si lo prefiere,

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 

Eso se compara con la edad en primer lugar, a continuación, apellido, y por último, si es necesario, nombre de pila.

+0

Genial, gracias. ¿Entonces Eq y Ord permitirán que la Persona sea ordenada naturalmente? –

+1

Sí, con una instancia 'Ord' (que requiere' Eq'), el 'estándar' estándar' de 'Data.List' está disponible para la clasificación. –

+0

Y si quisiera usar 'selection_sort_ord' (arriba) para ordenar una lista de elementos de Person en orden creciente de edad, usando la palabra clave' instance' para escribir mi propia función 'compare', cualquier sugerencia sobre cómo lo haría ¿esta? –

Cuestiones relacionadas