Haskell Show mapping for custom type

How can I tell haskell that when show is called in a list of variables of an algebraic type, "\ n" should be inserted after each line?

 type Customer = (Int, Int, [Int]) 

I tried to do this:

 instance of Show Customer where show x = x ++ "\n" 

but apparently I can create such instances for "data ...". How can i solve this?

I need to get show only for the list of clients, so when I show it, the output is easy to read, one client per line.

+6
source share
2 answers

To just display on different lines, do not change show , just do unlines (map show customerList) . This will show each of them, and then return them along with newlines between them.


However, you asked about a show change for the type synonym, so here are your options:

show is for basic data serialization. If you want to do something else, you have several options:

  • Write a function that does this on this instance.
  • Create your own Display class and determine how you like to stuff things in your display function.
  • Use newtype to transfer data.
  • Declare your own customer type.
  • Add new lines later

    type Customer = (Int, Int, [Int])

Example 1

 displayC :: Customer -> String displayC = (++"\n").show 

Example 2

 {-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-} class Display a where display :: a -> String instance Display Customer where display x = show x ++ "\n" 

(Note that you should say instance Display Customer , not instance of Display Customer .)

Output Example:

 *Main> display ((3,4,[5,6])::Customer) "(3,4,[5,6])\n" 

Use these language extensions with caution.

Example 3

 newtype Cust = Cust Customer displayCust (Cust c) = show c ++ "\n" 

Example 4

 data CustomerTup = CTup Int Int [Int] displayCTup (CTup ab cs) = show (a,b,cs) ++ "\n" 

or even better

 data CustomerRec = CRec {custno::Int, custAge::Int, custMeasurements::[Int]} deriving Show displayCRec r = show (custno r,custAge r,custMeasurements r) ++ "\n" 

where you can even stick to the show instance instance. The data path is good, because there is more type safety, and the record type stops you from making erroneous errors.

Example 5

 stuff = unlines $ map show [(1,2,[3,4]),(5,6,[7,8,9])] 

or even

 morestuff = unlines [show (1,2,[3,4]), show (5,6,[7,8,9]), "are all more numbery than", show (True,4,False)] 
+10
source

A small addition to AndrewC's excellent answer:

6. Write a function that adds a new line to the text representation of any type in the Show class:

 display :: Show a => a -> String display = flip shows "\n" 

For instance:

 > display (2, 3, [5, 7, 11]) "(2,3,[5,7,11])\n" 
+3
source

All Articles