转换putStrLn'd返回字符串的函数

时间:2017-05-05 08:22:16

标签: haskell types

standalone working script中,我有一个返回IO ()的函数:

main :: IO ()
main = do
    response <- simpleHttp "https://leonstafford.github.io"

    let body = decodeUtf8 ( response )
    let bodyAsString = unpack ( body )

    putStrLn $ htmlToPlainText bodyAsString

我现在正试图在this existing script中使用相同的功能,但在与公共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

我一直在摆弄它大约一个星期,并希望我已经能够在标题中定义足够的问题,因为它可能不是另一个can't match expected types帖子,虽然很漂亮确定就是这样。

1 个答案:

答案 0 :(得分:3)

关于Haskell的好处是,你可以一步一步地做到这一点,大多数情况下并不担心你会得到完全不同的行为。首先,我们将main的内容移动到一个新函数中:

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

接下来,我们将url添加为参数:

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"

最后,但并非最不重要的是,我们将putStrLn移至main并在return中使用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

这些步骤(进入新功能,添加参数,移出功能)非常小。所以当你遇到这样的问题时,不要害怕在两个步骤之间做一些事情。

请注意IO始终与renderPage保持一致,因为simpleHttp使用IO。一旦你在函数中的某个地方有它,就没有办法摆脱IO。但是renderPage的功能可以重复使用,因为

renderPage :: String -> IO String
renderPage = fmap (htmlToPlainText . unpack . decodeUtf8) . simpleHttp

因此:

utf8ToPlainText :: ByteString -> String
utf8ToPlainText = htmlToPlainText . unpack . decodeUtf8

renderPage :: String -> IO String
renderPage = fmap utf8ToPlainText . simpleHttp