更改函数以支持IO String而不是String [英] Change a function to support IO String instead of String
问题描述
import Data.Char
import Network.HTTP
import Text.HTML.TagSoup
openURL :: String - > IO字符串
openURL x = getResponseBody =<< simpleHTTP(getRequest x)
crawlType :: String - > IO字符串
crawlType pkm = do
src< - openURL url
return。 fromBody $ parseTags src
其中
fromBody = unwords。下降6。拿7。单词。 innerText。 dropWhile(〜/ =< p>)
url =http://pokemon.wikia.com/wiki/++ pkm
我想通过以下方式解析其数据:
getType ::字符串 - > (String,String)
getType pkmType =(dropWhile(=='/')$ fst b,dropWhile(=='/')$ snd b)
where b = break(=='/ ')pkmType
但是就像你看到的那样, getType
不支持IO字符串。
我是IO新手,那么如何使它工作?
我也尝试了解将IO字符串赋给该函数时的错误,但对于我来说这太复杂了:/ $ / $>
,强调: IO字符串
不是字符串。这是一个IO动作,当你将它绑定在 main
动作中的某个地方时,将会产生类型结果 String
,但你不应该把它看作某种字符串类型的变体。相反,它是 IO a
类型
由于这个原因,你几乎可以肯定地做,而不是想要改变一个函数来支持 IO字符串
而不是字符串
&rdquo ;. 而不是,您希望将此字符串接受函数应用于 crawlType
动作的结果。正如我所说的那样,这样的结果是输入 String
,所以你很好。例如,
main :: IO()
main = do
pkm =blablabla
typeString< - crawlType pkm
let typeSpec = getType typeString
print typeSpec - 或者您希望用它做的任何事情。
您可以通过编写省略 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
其中
fromBody = unwords。下降6。拿7。单词。 innerText。 dropWhile(〜/ =< p>)
url =http://pokemon.wikia.com/wiki/++ pkm
† 如果您好奇 < $>
运算符确实:这不是像 do /
< -
标记的内置语法。相反,它只是 fmap
的中缀版本,您可能在其列表中找到特殊版本 map
。列表 []
和 IO
都是函子,这意味着你可以通过普通函数来拉动它们,只改变元素/结果值,但不改变IO动作/列表脊柱结构。
I get an IO String via:
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
and I want to parse its data via:
getType :: String -> (String, String)
getType pkmType = (dropWhile (== '/') $ fst b, dropWhile (== '/') $ snd b)
where b = break (== '/') pkmType
But like you see, getType
doesn't support the IO String yet.
I'm new to IO, so how to make it working? I also tryed to understand the error when giving the IO String to that function, but it's too complicated for me up to now :/
First, to emphasize: an IO String
is not a string. It's an IO action which, when you bind it somewhere within the main
action, will yield a result of type String
, but you should not think of it as some sort of “variation on the string type”. Rather, it's a special instantiation of the IO a
type.
For this reason, you almost certainly do not want to “change a function to support IO String
instead of String
”. Instead, you want to apply this string-accepting function, as it is, to an outcome of the crawlType
action. Such an outcome, as I said, has type String
, so you're fine there. For instance,
main :: IO ()
main = do
pkm = "blablabla"
typeString <- crawlType pkm
let typeSpec = getType typeString
print typeSpec -- or whatever you wish to do with it.
You can omit the typeString
variable by writing†
typeSpec <- getType <$> crawlType pkm
if you prefer; this corresponds to what in a procedural language might look like
var typeSpec = getType(crawlType(pkm));
Alternatively, you can of course include the parsing right in 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
†If you're curious what the <$>
operator does: this is not built-in syntax like do
/<-
notation. Instead, it's just an infix version of fmap
, which you may better know in its list-specialised version map
. Both list []
and IO
are functors, which means you can pull them through ordinary functions, changing only the element/outcome values but not the structure of the IO action / list spine.
这篇关于更改函数以支持IO String而不是String的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!