2

我正在从事我在这里从事的项目:

我如何提前做一个块返回?

我在函数中使用了 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,因为我希望将所有的替换为mapMliftIO查看性能差异。

[更新]

所以事实证明我不需要做任何类型的杂技,我只需要一种方法将回复节点变成我在这里找到的根节点。

由于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 ()
4

1 回答 1

5

让我们看看你的“monad runner”的类型

liftM (fromMaybe ()) . runMaybeT :: MaybeT IO () -> IO ()

所以我们需要 do 块的每一行都有 type MaybeT IO ()。因为mapM_ :: (a -> m b) -> [a] -> m ()我们需要parseReply url (fromJust page_id)的类型MaybeT IO ()不仅仅是Maybe ().

幸运的是,正如人们所希望的那样,很容易注入MaybeMaybeT IO

parseReplyT :: Monad m => String -> String -> XNode -> MaybeT m ()
parseReplyT url op_id = MaybeT . return . parseReply url op_id
于 2013-04-22T22:28:35.030 回答