Marcio
Marcio

Reputation: 351

How can I break line on Haskell?

I tried break line using \n, putStrLn and print but nothing works.

When I use \n the result only concatenates the strings, and when I use putStrLn or print I receive a type error.

Output for \n:

formatLines [("a",12),("b",13),("c",14)]
"a...............12\nb...............13\nc...............14\n"

Output for putStrLn:

format.hs:6:22:
    Couldn't match type `IO ()' with `[Char]'
    Expected type: String
      Actual type: IO ()
    In the return type of a call of `putStrLn'
    In the expression:
      putStrLn (formatLine ((fst x), (snd x)) ++ formatLines xs)
    In an equation for `formatLines':
        formatLines (x : xs)
          = putStrLn (formatLine ((fst x), (snd x)) ++ formatLines xs)
Failed, modules loaded: none.

the output for print is the same as that of putStrLn

Here is my code:

formatLine :: (String,Integer) -> String
formatLine (s, i) = s ++ "..............." ++ show i

formatLines::[(String,Integer)] -> String
formatLines [] = ""
formatLines (x:xs) = print (formatLine ((fst x), (snd x)) ++ formatLines xs) 

I understand the reason of the error for print and putStrLn but i have no idea how fix it.

Upvotes: 0

Views: 3134

Answers (2)

chi
chi

Reputation: 116139

Split your code in two parts.

One part simply constructs the string. Use "\n" for newlines.

The second part takes the string and applies putStrLn (NOT print) to it. The newlines will get printed correctly.

Example:

foo :: String -> Int -> String
foo s n = s ++ "\n" ++ show (n*10) ++ "\n" ++ s

bar :: IO ()
bar = putStrLn (foo "abc" 42)
    -- or putStr (...) for no trailing newline

baz :: String -> IO ()
baz s = putStrLn (foo s 21)

If you use print instead, you'll print the string representation, with quotes and escapes (like \n) inside it. Use print only for values that have to be converted to string, like numbers.

Also note that you can only do IO (like printing stuff) in functions whose return type is IO (something).

Upvotes: 5

shree.pat18
shree.pat18

Reputation: 21757

You need to print the results to output.

This is an IO action, and so you cannot have a function signature ending with -> String. Instead, as @chi points out, the return type should be IO (). Further, since you have the function to generate formatted string already, all you need is a function to help you map the printing action over your input list. This you can do using mapM_, like so:

formatLines::[(String,Integer)] -> IO ()
formatLines y = mapM_ (putStrLn . formatLine) y

Demo

Upvotes: 1

Related Questions