Haskell不计算块

Haskell不计算块,haskell,http-conduit,Haskell,Http Conduit,我正在编写简单的sitemap.xml爬虫。代码如下。我的问题是为什么main末尾的代码不打印任何内容。我怀疑这是因为haskell的懒惰,但不知道如何应对: import Network.HTTP.Conduit import qualified Data.ByteString.Lazy as L import Text.XML.Light import Control.Monad.Trans (liftIO) import Control.Monad import Data.String.U

我正在编写简单的sitemap.xml爬虫。代码如下。我的问题是为什么
main
末尾的代码不打印任何内容。我怀疑这是因为haskell的懒惰,但不知道如何应对:

import Network.HTTP.Conduit
import qualified Data.ByteString.Lazy as L
import Text.XML.Light
import Control.Monad.Trans (liftIO)
import Control.Monad
import Data.String.Utils
import Control.Exception

download :: Manager -> Request -> IO (Either HttpException L.ByteString)
download manager req = do
  try $
    fmap responseBody (httpLbs req manager)

downloadUrl :: Manager -> String -> IO (Either HttpException L.ByteString)
downloadUrl manager url = do
  request <- parseUrl url
  download manager request

getPages :: Manager -> [String] -> IO [Either HttpException L.ByteString]
getPages manager urls =
  sequence $ map (downloadUrl manager) urls

main = withManager $ \ manager -> do
  -- I know simpleHttp is bad here
  mapSource <- liftIO $ simpleHttp "http://example.com/sitemap.xml"

  let elements = (parseXMLDoc mapSource) >>= Just . findElements (mapElement "loc")
      Just urls = liftM (map $ (replace "/#!" "?_escaped_fragment_=") . strContent) elements
      mapElement name = QName name (Just "http://www.sitemaps.org/schemas/sitemap/0.9") Nothing

  return $
    getPages manager urls >>= \ pages -> do
      print "evaluate me!"
      sequence $ map print pages
import Network.HTTP.conductor
将限定的Data.ByteString.Lazy作为L导入
导入Text.XML.Light
进口控制单体转运(liftIO)
进口管制
导入Data.String.Utils
导入控制。异常
下载::管理器->请求->IO(HttpException L.ByteString)
下载管理器req=do
试一试$
fmap响应库(httpLbs请求管理器)
下载URL::Manager->String->IO(HttpException L.ByteString)
下载url管理器url=do
请求[String]->IO[HttpException L.ByteString]中的任意一个]
getPages管理器URL=
序列$map(下载URL管理器)URL
main=withManager$\manager->do
--我知道simpleHttp在这里很糟糕
mapSource>=仅此而已。findElements(地图元素“loc”)
Just url=liftM(map$(replace”/#!“”?_转义的_fragment_=“).strContent)元素
mapElement名称=QName名称(仅限“http://www.sitemaps.org/schemas/sitemap/0.9)没有
返回$
getPages管理器URL>>=\pages->do
打印“评估我!”
序列$地图打印页

runResourceT
()替换上一个
返回值。正如它的类型所暗示的那样,它会将ResourceT转换为IO操作。

runResourceT
()替换上一次的
返回。正如它的类型所暗示的那样,它会将ResourceT转换为IO操作。

您遇到的问题与我在这里描述的问题相同,至少是因为有错误的代码进行类型检查,而实际上它应该给出一个类型错误:。这就是为什么您应该总是显式地给
main
类型签名
main::IO()


要解决此问题,您需要将
return
替换为
lift
(请参阅),并将
sequence$map…
替换为
mapM
mapM\uf
相当于
sequence\uf。map f

您遇到的问题与我在这里描述的问题相同,至少是因为有不正确的代码,当它实际上应该给出一个类型错误时会进行类型检查:。这就是为什么您应该总是显式地给
main
类型签名
main::IO()


要解决此问题,您需要将
return
替换为
lift
(请参阅),并将
sequence$map…
替换为
mapM
mapM\uf
相当于
sequence\uf。映射f

为什么要在
返回中包装
getPages
?它似乎没有必要。@arrowdodger未返回I get编译错误:
无法将类型“IO”与“Control.Monad.Trans.Resource.Internal.ResourceT m”匹配预期类型:Control.Monad.Trans.Resource.Internal.ResourceT m[HttpException L.ByteString]实际类型:IO[HttpException L.ByteString中的任意一个]
为什么要在
return
中包装
getPages
?这似乎不必要。@arrowdoger没有返回,我得到编译错误:
无法将类型“IO”与“Control.Monad.Trans.Resource.Internal.ResourceT m”匹配预期类型:Control.Monad.Trans.Resource.Internal.ResourceT m[Orther HttpException L.ByteString]实际类型:IO[Orther HttpException L.ByteString]
但编译器(和文档)说我需要资源,而不是IO()哦,现在我明白了。您可能需要
safeFromIOBase
:但编译器(和文档)说我需要资源,而不是IO()哦,现在我明白了。你可能需要
safeFromIOBase
:谢谢,它很有帮助!现在我知道显式键入和模块化无处不在是获胜的方法。这是工作版本:谢谢,它很有帮助!现在我知道显式键入和模块化无处不在是获胜的方法。这是工作版本: