Reputation: 4483
In a standalone working script, I have a function returning IO ()
as such:
main :: IO ()
main = do
response <- simpleHttp "https://leonstafford.github.io"
let body = decodeUtf8 ( response )
let bodyAsString = unpack ( body )
putStrLn $ htmlToPlainText bodyAsString
I'm now trying to utilise same function in this existing script, but struggling with the common Couldn't match type ‘[Char]’ with ‘Char’
:
renderPage :: String -> String
renderPage url = do
response <- simpleHttp url
let body = decodeUtf8 ( response )
bodyAsString = unpack ( body )
articleAsPlainText = htmlToPlainText bodyAsString
return articleAsPlainText
I have been fiddling with it off and on for about a week and hope I've been able to define the issue enough in the title, so as it may not be yet another can't match expected types
post, though am pretty sure it is just that.
Upvotes: 1
Views: 119
Reputation: 105876
The nice thing about Haskell is that you can do that step by step, mostly without fearing that you get completely different behaviour. First of all, we move the content of main
into a new function:
renderPage :: IO ()
renderPage = do
response <- simpleHttp "https://leonstafford.github.io"
let body = decodeUtf8 ( response )
let bodyAsString = unpack ( body )
putStrLn $ htmlToPlainText bodyAsString
main :: IO ()
main = renderPage
Next, we add the url
as argument:
renderPage :: String -> IO ()
renderPage url = do
response <- simpleHttp url
let body = decodeUtf8 ( response )
let bodyAsString = unpack ( body )
putStrLn $ htmlToPlainText bodyAsString
main :: IO ()
main = renderPage "https://leonstafford.github.io"
And last, but not least, we move putStrLn
into main
and use return
in renderPage
:
renderPage :: String -> IO String
renderPage url = do
response <- simpleHttp url
let body = decodeUtf8 ( response )
let bodyAsString = unpack ( body )
return $ htmlToPlainText bodyAsString
main :: IO ()
main = renderPage "https://leonstafford.github.io" >>= putStrLn
Those steps (move into new function, add arguments, move functionality out) were pretty small. So when you encounter a problem like this, don't be afraid to do some inbetween steps.
Note that IO
always stays with renderPage
, since simpleHttp
uses IO
. There is no way to get rid of IO
once you have it somewhere in a function. But the functionality of renderPage
can be re-used, since
renderPage :: String -> IO String
renderPage = fmap (htmlToPlainText . unpack . decodeUtf8) . simpleHttp
and therefore:
utf8ToPlainText :: ByteString -> String
utf8ToPlainText = htmlToPlainText . unpack . decodeUtf8
renderPage :: String -> IO String
renderPage = fmap utf8ToPlainText . simpleHttp
Upvotes: 3