【问题标题】:Change a function to support IO String instead of String更改一个函数以支持 IO String 而不是 String
【发布时间】:2016-02-24 21:42:47
【问题描述】:

我通过以下方式获得一个 IO 字符串:

import Data.Char
import Network.HTTP
import Text.HTML.TagSoup

openURL :: String -> IO String
openURL x = getResponseBody =<< simpleHTTP (getRequest x)

crawlType :: String -> IO String
crawlType pkm = do
  src <- openURL url
  return . fromBody $ parseTags src
  where
    fromBody = unwords . drop 6 . take 7 . words . innerText . dropWhile (~/= "<p>")
    url = "http://pokemon.wikia.com/wiki/" ++ pkm

我想通过以下方式解析其数据:

getType :: String -> (String, String)
getType pkmType = (dropWhile (== '/') $ fst b, dropWhile (== '/') $ snd b)
                  where b = break (== '/') pkmType

但如你所见,getType 还不支持 IO 字符串。

我是 IO 新手,那么如何让它发挥作用? 在将 IO 字符串提供给该函数时,我也尝试理解错误,但到目前为止对我来说太复杂了:/

【问题讨论】:

    标签: haskell io


    【解决方案1】:

    首先,强调:IO String 不是字符串。这是一个 IO 操作,当您将其绑定到 main 操作中的某个位置时,将产生类型为 String 的结果,但您不应将其视为某种“对字符串类型”。相反,它是 IO a 类型的特殊实例

    出于这个原因,您几乎肯定想要“更改一个函数以支持IO String 而不是String”。 相反,您希望将这个字符串接受函数原样应用于crawlType 操作的结果。正如我所说,这样的结果类型为String,所以你在那里很好。例如,

    main :: IO ()
    main = do
       pkm = "blablabla"
       typeString <- crawlType pkm
       let typeSpec = getType typeString
       print typeSpec -- or whatever you wish to do with it.
    

    你可以省略typeString变量,写成

       typeSpec <- getType <$> crawlType pkm
    

    如果您愿意;这对应于程序语言中的样子

       var typeSpec = getType(crawlType(pkm));
    

    或者,你当然可以在crawlType中包含解析权:

    crawlType' :: String -> IO (String, String)
    crawlType' pkm = do
      src <- openURL url
      return . getType . fromBody $ parseTags src
      where
        fromBody = unwords . drop 6 . take 7 . words . innerText . dropWhile (~/= "<p>")
        url = "http://pokemon.wikia.com/wiki/" ++ pkm
    

    如果您好奇 &lt;$&gt; operator 的作用:这不是像 do/&lt;- 表示法这样的内置语法。相反,它只是fmap 的中缀版本,您可能会在其列表专用版本map 中更好地了解它。列表[]IO 都是functors,这意味着您可以通过普通函数拉取它们,只更改元素/结果值,而不更改 IO 操作/列表脊的结构。

    【讨论】:

    • 这个答案太棒了。你帮了我很多。谢谢!
    猜你喜欢
    • 2011-07-11
    • 1970-01-01
    • 2020-07-22
    • 2012-12-05
    • 1970-01-01
    • 2011-05-23
    • 2012-09-12
    • 1970-01-01
    • 2023-02-16
    相关资源
    最近更新 更多