1

I've written a basic recursive function:

bibliography_rec :: [(String, String, Int)] -> String
bibliography_rec [] = ""
bibliography_rec (x:xs) = (citeBook x) ++ "\n" ++ (bibliography_rec xs)

citeBook simply reformats the tuple into a String.

When run with this input:

ghci> bibliography_rec [("Herman Melville", "Moby Dick", 1851),("Georgy Poo", "Alex Janakos", 1666)]

It produces:

"Moby Dick (Herman Melville, 1851)\nAlex Janakos (Georgy Poo, 1666)\n"

I need line by line printing so I used this:

bibliography_rec (x:xs) = putStr ((citeBook x) ++ "\n" ++ (bibliography_rec xs))

My problem is my output NEEDS to be of type String NOT IO ()

I've been stuck on this for way too long so any help is great!

1
  • 3
    Values of type String cannot produce output. So your requirements ("I must produce output" and "the return type must be String") are in conflict. Commented Jan 11, 2016 at 21:19

1 Answer 1

5

Looks like you're already there, you just need to putStrLn the string instead of printing it (which is what ghci does by default). print runs its argument through show first, so it will quote the escape characters like "\n".

ghci> putStrLn $ bibliography_rec [...]
Sign up to request clarification or add additional context in comments.

3 Comments

Only problem is I need to generate the String with only ghci> bibliography_rec [(...),(...)] or is there something im still missing. Also what does the $ do??
@ajanakos There's definitely something you're missing. A String value is just a String value, in Haskell that means that it has no side effects and simply can't do things like print a value to the screen. In GHCi when you evaluate a value, it performs an IO action behind the scenes so that you get to see a representation of that value displayed, since otherwise the "interactive" part of GHCi wouldn't really be useful. Note that code entered into GHCi is not the same as executing a .hs file.
@ajanakos The $ operator has many, many discussions, clarifications, etc all over stackoverflow and the rest of the internet, I won't go into detail here, but suffice to say that it's a do-nothing operator with a specific order of operations so that you can drop parentheses frequently. The above line of code could have been equivalently written as putStrLn (bibliography_rec [...]) and it would have been identical in execution. This comes in handy with things like f $ g $ h 1 instead of f (g (h 1))), where the parens mostly just add noise.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.