更改函数以支持IO String而不是String [英] Change a function to support IO String instead of String

查看:103
本文介绍了更改函数以支持IO String而不是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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆