return
in Haskell non fare la stessa cosa come return
in altre lingue. Invece, ciò che fa return
consiste nell'iniettare un valore in una monade (in questo caso IO
). Hai un paio di opzioni
il più semplice è quello di utilizzare se
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()
un'altra opzione è quella di utilizzare 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()
il problema generale qui è che la monade IO
non ha effetti di controllo (tranne eccezioni). D'altra parte, si potrebbe usare il trasformatore forse monade
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()
se si vuole davvero ottenere effetti in piena regola di controllo è necessario utilizzare 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()
ATTENZIONE: nessuno di codice di cui sopra è stato testato, o anche controllato!
fonte
2013-03-15 21:15:25
È questo quello che vuoi? http://www.haskellforall.com/2012/07/breaking-from-loop.html –