Ina*_*thi 5 curl haskell types type-conversion
好吧,我正试图在Haskell中围绕IO,我想我会写一个处理网页的小应用程序来做它.我越来越绊倒在是片段(与道歉bobince,虽然是公平的,我不试图解析此HTML,只提取一个或两个值):
titleFromUrl url = do
(_, page) <- curlGetString url [CurlTimeout 60]
matchRegex (mkRegexWithOpts "<title>(.*?)</title>" False True) page
Run Code Online (Sandbox Code Playgroud)
上面应该采用字符串形式的URL,扫描它指向的页面matchRegex,然后返回Nothing或者Just [a],a匹配(可能是多行)字符串.令人沮丧的是,当我尝试做的时候
Prelude> (_, page) <- curlGetString url [CurlTimeout 60]
Prelude> matchRegex (mkRegexWithOpts "<title>(.*?)</title>" False True) page
Run Code Online (Sandbox Code Playgroud)
在翻译中,它正是我想要的.当我尝试加载相同的表达式,并imports从文件关联时,它给我一个类型推断错误,说明它couldn't match expected type 'IO b' against inferred type 'Maybe [String]'.这告诉我,我错过了一些小而基本的东西,但我无法弄清楚是什么.我已经尝试过显式地转换page为字符串,但这只是迷信编程(并且它在任何情况下都不起作用).
任何提示?
是的,GHCi接受任何价值.你可以说:
ghci> 4
4
ghci> print 4
4
Run Code Online (Sandbox Code Playgroud)
但这两个值(4和print 4)显然不相等.神奇的GHC正在做的是,如果你输入的内容评估为a IO something然后它执行该动作(如果something不是则打印结果()).如果没有,则调用show该值并打印出来.无论如何,你的程序无法访问这个魔法.
当你说:
do foo <- bar :: IO Int
baz
Run Code Online (Sandbox Code Playgroud)
baz预计是类型IO something,否则是类型错误.这将允许您执行I/O然后返回纯值.你可以检查一下,注意到上述产量:
bar >>= (\foo -> baz)
Run Code Online (Sandbox Code Playgroud)
和
-- (specializing to IO for simplicity)
(>>=) :: IO a -> (a -> IO b) -> IO b
Run Code Online (Sandbox Code Playgroud)
因此
bar :: IO a
foo :: a
baz :: IO b
Run Code Online (Sandbox Code Playgroud)
修复它的方法是使用以下return函数将返回值转换为IO值:
return :: a -> IO a -- (again specialized to IO)
Run Code Online (Sandbox Code Playgroud)
那么你的代码是:
titleFromUrl url = do
(_, page) <- curlGetString url [CurlTimeout 60]
return $ matchRegex (mkRegexWithOpts "<title>(.*?)</title>" False True) page
Run Code Online (Sandbox Code Playgroud)
对于大多数上述讨论的,可以替代任何单子IO(例如Maybe,[]...),它仍然是真实的.
| 归档时间: |
|
| 查看次数: |
869 次 |
| 最近记录: |