Reputation: 1190
How can I tell haskell that when show
is called on a list of variables of algebraic type, a "\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 only create such instances for "data...." kind of things. How can I solve this?
I need to derive Show
just for a list of Customers, so that when I display it, the output is easily readable, one customer per line.
Upvotes: 7
Views: 4908
Reputation: 8050
A small addition to AndrewC's excellent answer:
6. Write a function that adds a new line to the textual representation of any type in the class Show
:
display :: Show a => a -> String
display = flip shows "\n"
For example:
> display (2, 3, [5, 7, 11])
"(2,3,[5,7,11])\n"
Upvotes: 3
Reputation: 32455
To just display on different lines, don't change show
, just do unlines (map show customerList)
. This will show each of them, then put them back together with newline characters inbetween.
However, you asked about changing show for a type
synonym, so here are your options for that:
show
is for basic serialisation of the data. If you want to do something different, you've got a few options:
display
function.newtype
to wrap the data.Add newlines 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"
(Notice you should say instance Display Customer
rather than instance of Display Customer
.)
Example output:
*Main> display ((3,4,[5,6])::Customer)
"(3,4,[5,6])\n"
Those language extensions should be used with caution, though.
Example 3
newtype Cust = Cust Customer
displayCust (Cust c) = show c ++ "\n"
Example 4
data CustomerTup = CTup Int Int [Int]
displayCTup (CTup a b 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 might even stick with the Show
instance way of doing things. The data
way is good because there's more type safety, and the record type stops you making trivial wrong position mistakes.
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)]
Upvotes: 10