user2240649
user2240649

Reputation: 89

Haskell - Formatting issues

this is the current code I have to displaying a database worth of information, but when printing this out it isn't very clear to read..

type Title = String
type Cast = String
type Year = Int
type Fans = String

type Film = (Title, [Cast], Year, [Fans])
type Database = [Film]

testDatabase :: Database
testDatabase = [("Casino Royale", ["Daniel Craig", "Eva Green", "Judi Dench"], 2006, ["Garry", "Dave", "Zoe", "Kevin", "Emma"]),
    ("Cowboys & Aliens", ["Harrison Ford", "Daniel Craig", "Olivia Wilde"], 2011, ["Bill", "Jo", "Garry", "Kevin", "Olga", "Liz"]),     
        ("Catch Me If You Can", ["Leonardo DiCaprio", "Tom Hanks"], 2002, ["Zoe", "Heidi", "Jo", "Emma", "Liz", "Sam", "Olga", "Kevin", "Tim"])]      

when running this function:

displayAllFilms :: Database ->[(Title, [Cast], Year, [Fans])]
displayAllFilms [] = []
displayAllFilms ((i, j, k, l): xs)
        |l == [] = (i, j, k, []) : displayAllFilms xs
        |otherwise = (i, j, k, l) : displayAllFilms xs

It prints this:

[("Casino Royale",["Daniel Craig","Eva Green","Judi Dench"],2006 ["Garry","Dave","Zoe","Kevin","Emma"]),("Cowboys & Aliens",["Harrison Ford","Daniel Craig","Olivia Wilde"],2011,["Bill","Jo","Garry","Kevin","Olga","Liz"]),("Catch Me If You Can",["Leonardo DiCaprio","Tom Hanks"],2002,["Zoe","Heidi","Jo","Emma","Liz","Sam","Olga","Kevin","Tim"])]

which clearly is not readable: is there a way to make each film information (in this case) be printed on separate lines ie. utilising the /n notation?

Help would be much appreciated, thanks in advance! :)

Upvotes: 2

Views: 183

Answers (1)

dave4420
dave4420

Reputation: 47062

displayAllFilms :: Database -> IO ()
displayAllFilms db = mapM_ print db

How does this work?

  • print is defined as

    print :: Show a => a -> IO ()
    print x = putStrLn (show x)
    
  • How to explain mapM_?... You know what map does, yes? Given a function and a list, it applies the function to each element of the list, and gives back a list of the results.

    map takes a function of type a -> b, but mapM_ takes a function of type a -> IO b (I am simplifying). The IO means that the function may perform some i/o (in this case: writing to the screen, that's what print does).

    mapM_ joins all those individual pieces of i/o together and ensures they occur in the right order.

Notes:

  • your original displayAllFilms doesn't actually do anything: the output is the same as the input, the only reason anything gets printed to the screen is that you're running it from the ghci prompt
  • it's spelled \n, not /n (although I am not using it explicitly because print/putStrLn add a newline at the end automatically)

Upvotes: 5

Related Questions