我正在从事我在这里从事的项目:
我在函数中使用了 monad 转换器方法,看起来像这样:
scrapePost :: String -> IO ()
scrapePost url = liftM (fromMaybe ()) . runMaybeT $ do
doc <- lift $ fromUrl url
-- get a bunch of stuff from the page
-- send it to the db
replies <- lift . runX $ doc >>> css ".post.reply"
-- here is the problem
mapM_ (parseReply url (fromJust page_id)) replies
-- here is the problem
parseReply
是我需要的功能,但我似乎无法正确处理。
这是我启动该功能的微弱尝试:
parseReply :: String -> String -> XNode -> Maybe ()
parseReply url op_id reply = do
reply_id <- runX $ reply ! "id"
return ()
顺便说一句,我正在使用 HandsomeSoup
我将像scrapePost
使用设置 css 规则的函数一样操作,以抓取、删除不包含所有值的回复,并将它们发送到数据库。
我想使用mapM
,因为我希望将所有的替换为mapM
并liftIO
查看性能差异。
[更新]
所以事实证明我不需要做任何类型的杂技,我只需要一种方法将回复节点变成我在这里找到的根节点。
由于parseReply
仅在MaybeT IO ()
上下文中使用,因此其类型不需要更改并且scrapePost
可以保持不变。
parseReply
变成:
toRoot :: ArrowXml a => XmlTree -> a n XmlTree
toRoot node = root [] [constA node]
parseReply :: String -> String -> XmlTree -> MaybeT IO ()
parseReply url op_id reply = do
let node = toRoot reply
reply_id <- lift . liftM (`atMay` 0) $ runX $ node >>> css "div" ! "id"
guard (isJust reply_id)
return ()