代码之家  ›  专栏  ›  技术社区  ›  Inaimathi

哈斯克尔卷曲帮助

  •  5
  • Inaimathi  · 技术社区  · 15 年前

    好吧,我在哈斯凯尔试着把我的头绕在IO上,我想我会写一个小程序来处理网页。我被这段话绊倒了(向你道歉) bobince 尽管公平地说,我并不想 解析 此处为HTML,只提取一个或两个值):

    titleFromUrl url = do
        (_, page) <- curlGetString url [CurlTimeout 60]   
        matchRegex (mkRegexWithOpts "<title>(.*?)</title>" False True) page
    

    上面应该采用字符串形式的URL,扫描它指向的页面 matchRegex ,然后返回 Nothing Just [a] ,在哪里 a 是匹配的(可能是多行)字符串。令人沮丧的是当我试着做的时候

    Prelude> (_, page) <- curlGetString url [CurlTimeout 60]
    Prelude> matchRegex (mkRegexWithOpts "<title>(.*?)</title>" False True) page
    

    在口译员中,它完全按照我的要求来做。当我尝试加载相同的表达式时,并且 imports 从一个文件中,它给了我一个类型推断错误,说明 couldn't match expected type 'IO b' against inferred type 'Maybe [String]' . 这说明我遗漏了一些小而基本的东西,但我不知道是什么。我试过明确地选演员 page 一个字符串,但这只是一个迷信编程(在任何情况下都不起作用)。

    有什么提示吗?

    1 回复  |  直到 15 年前
        1
  •  8
  •   luqui    15 年前

    是的,GHCI接受任何价值。你可以说:

    ghci> 4
    4
    ghci> print 4
    4
    

    但这两个价值观( 4 print 4 )显然不平等。神奇的是,如果您键入的值为 IO something 然后执行该操作(并打印结果,如果 something 不是 () )如果没有,它就会打电话 show 在价值和打印。无论如何,你的程序无法访问这个魔法。

    当你说:

    do foo <- bar :: IO Int
       baz
    

    baz 应为类型 IO某物 ,否则是类型错误。这将允许您执行I/O,然后返回一个纯值。您可以检查这一点,注意去除上述物质会产生:

    bar >>= (\foo -> baz)
    

    -- (specializing to IO for simplicity)
    (>>=) :: IO a -> (a -> IO b) -> IO b
    

    因此

    bar :: IO a
    foo :: a
    baz :: IO b
    

    修复它的方法是使用 return 功能:

    return :: a -> IO a  -- (again specialized to IO)
    

    您的代码是:

    titleFromUrl url = do
        (_, page) <- curlGetString url [CurlTimeout 60]   
        return $ matchRegex (mkRegexWithOpts "<title>(.*?)</title>" False True) page
    

    在上面的大多数讨论中,您可以用任何monad替换 IO (例如) Maybe , [] ,…)它仍然是真的。

    推荐文章