gpt4 book ai didi

haskell - 如何让 do block 提前返回?

转载 作者:行者123 更新时间:2023-12-02 07:13:08 25 4
gpt4 key购买 nike

我正在尝试使用 Haskell 抓取网页并将结果编译到一个对象中。

如果出于某种原因,我无法从页面获取所有项目,我想停止尝试处理页面并提前返回。

例如:

scrapePage :: String -> IO ()
scrapePage url = do
doc <- fromUrl url
title <- liftM headMay $ runX $ doc >>> css "head.title" >>> getText
when (isNothing title) (return ())
date <- liftM headMay $ runX $ doc >>> css "span.dateTime" ! "data-utc"
when (isNothing date) (return ())
-- etc
-- make page object and send it to db
return ()

问题是 when 不会停止 do block 或阻止其他部分执行。

执行此操作的正确方法是什么?

最佳答案

haskell 中的

return 与其他语言中的 return 的作用不同。相反,return 的作用是将一个值注入(inject)到 monad 中(在本例中为 IO)。您有几个选择

最简单的是使用if

scrapePage :: String -> IO ()
scrapePage url = do
doc <- fromUrl url
title <- liftM headMay $ runX $ doc >>> css "head.title" >>> getText
if (isNothing title) then return () else do
date <- liftM headMay $ runX $ doc >>> css "span.dateTime" ! "data-utc"
if (isNothing date) then return () else do
-- etc
-- make page object and send it to db
return ()

另一种选择是使用unless

scrapePage url = do
doc <- fromUrl url
title <- liftM headMay $ runX $ doc >>> css "head.title" >>> getText
unless (isNothing title) do
date <- liftM headMay $ runX $ doc >>> css "span.dateTime" ! "data-utc"
unless (isNothing date) do
-- etc
-- make page object and send it to db
return ()

这里的普遍问题是IO monad没有控制效果(异常(exception)情况除外)。另一方面,您可以使用 Maybe monad 转换器

scrapePage url = liftM (maybe () id) . runMaybeT $ do
doc <- liftIO $ fromUrl url
title <- liftIO $ liftM headMay $ runX $ doc >>> css "head.title" >>> getText
guard (isJust title)
date <- liftIO $ liftM headMay $ runX $ doc >>> css "span.dateTime" ! "data-utc"
guard (isJust date)
-- etc
-- make page object and send it to db
return ()

如果你真的想获得完整的控制效果,你需要使用ContT

scrapePage :: String -> IO ()
scrapePage url = runContT return $ do
doc <- fromUrl url
title <- liftM headMay $ runX $ doc >>> css "head.title" >>> getText
when (isNothing title) $ callCC ($ ())
date <- liftM headMay $ runX $ doc >>> css "span.dateTime" ! "data-utc"
when (isNothing date) $ callCC ($ ())
-- etc
-- make page object and send it to db
return ()

警告:以上代码均未经过测试,甚至没有进行类型检查!

关于haskell - 如何让 do block 提前返回?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15441956/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com