jckuri

DownloadFileWithMonadTransformer.hs

Jun 16th, 2013
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- DownloadFileWithMonadTransformer.hs
  2. -- Inspired by:
  3. -- http://www.haskell.org/haskellwiki/Monad_Transformers_Tutorial
  4. -- http://stackoverflow.com/questions/11514671/haskell-network-http-incorrectly-downloading-image
  5.  
  6. import qualified Data.ByteString as B
  7. import Network.HTTP
  8. import Network.URI (parseURI)
  9. import Control.Monad.Trans
  10.  
  11. newtype MaybeT m a = MaybeT {
  12.  runMaybeT :: m (Maybe a)
  13. }
  14.  
  15. instance Monad m => Monad (MaybeT m) where
  16.  return x = MaybeT (return (Just x))
  17.  MaybeT action >>= f =
  18.   MaybeT $
  19.    action >>= \result ->
  20.    case result of
  21.     Nothing -> return Nothing
  22.     Just x -> runMaybeT (f x)
  23.  
  24. instance MonadTrans MaybeT where
  25.  lift action = MaybeT $ action >>= \result -> return (Just result)
  26.  
  27. zeroResponse :: IO B.ByteString
  28. zeroResponse = return $ B.empty
  29.  
  30. downloadWithMonadTransformer :: String -> MaybeT IO B.ByteString
  31. downloadWithMonadTransformer url =
  32.  return (parseURI url) >>= \parsingResult ->
  33.  case parsingResult of
  34.   (Just uri) ->
  35.    lift (putStrLn $ "Fetching link: " ++ show uri) >>
  36.    lift (simpleHTTP (defaultGETRequest_ uri)) >>= \http ->
  37.    lift (getResponseCode http) >>= \responseCode ->
  38.    if responseCode == (2,0,0) then
  39.     lift (getResponseBody http)
  40.    else
  41.     (lift $ putStrLn $ "HTTP response had error code: " ++ show responseCode) >>
  42.     (lift $ zeroResponse)
  43.   Nothing ->
  44.    (lift (putStrLn $ "Ill-formed link: " ++ url)) >>
  45.    (lift $ zeroResponse)
  46.    
  47. downloadAndSaveWithMonadTransformer url filepath =
  48.  (lift $ putStrLn "\nTrying to download and save:") >>
  49.  downloadWithMonadTransformer url >>= \file ->
  50.  if B.length file == 0 then
  51.   return ()
  52.  else
  53.   lift (putStrLn $ "Writing file: " ++ filepath) >>
  54.   lift (B.writeFile filepath file)
  55.  
  56. main =
  57.  runMaybeT (downloadAndSaveWithMonadTransformer "http://www.irregularwebcomic.net/comics/irreg2557.jpg" "irreg2557 - with monad transformer.jpg") >>
  58.  runMaybeT (downloadAndSaveWithMonadTransformer "http://www.irregularwebcomic.net/comics/inexistent.html" "irreg2557 - with monad transformer.jpg") >>
  59.  runMaybeT (downloadAndSaveWithMonadTransformer "illformed.net/error.txt" "error.txt")
Add Comment
Please, Sign In to add comment