Haskell不计算块
我正在编写简单的sitemap.xml爬虫。代码如下。我的问题是为什么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
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
:谢谢,它很有帮助!现在我知道显式键入和模块化无处不在是获胜的方法。这是工作版本:谢谢,它很有帮助!现在我知道显式键入和模块化无处不在是获胜的方法。这是工作版本: