HiveBrain v1.2.0
Get Started
← Back to all entries
patternModerate

Simple xkcd comic downloader

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
xkcddownloadercomicsimple

Problem

I'd really appreciate some harsh/constructive criticism of what I would consider as my first program in Haskell. The program should download all of the xkcd comics into a folder in the current directory.

I basically just threw the kitchen sink at it, using anything I found remotely interesting in RWH and on the Haskell wiki, so I'm 99% sure most of it is unnecessary or overkill. I tried using most popular libraries I could find.
I wasn't clear on how to handle errors, how to deal with the filesystem efficiently, and how to use Text.JSON correctly.

hpaste link

```
{-# Language PackageImports #-}
module Main where

import System.FilePath (takeFileName, ())
import System.IO
import System.Environment
import System.Posix.User
import System.Directory
import Control.Monad (liftM, forM_, replicateM_)
import Control.Concurrent (forkIO)
import Control.Concurrent.STM
import Data.List (delete)
import Network.HTTP
import qualified Data.ByteString.Lazy.Char8 as L
import "mtl" Control.Monad.Error
import Network.URI (parseURI)
import Control.Applicative
import Control.Exception
import qualified Network.Stream as Stream (Result)
import Control.Arrow
import Text.JSON

----------------------------------------------------------------------
main = do
dir comics) $ writeTChan comicQueue
workers IO (Either IOException (Stream.Result (Response String)))

tryRequest = try . simpleHTTP

simpleHttpE request = do
response throwError $ show err
Right rsp -> return rsp

getResponseBodyE = either (throwError.show) (return.rspBody)

fetchHtmlA = Kleisli getRequestE >>>
Kleisli simpleHttpE >>>
Kleisli getResponseBodyE

fetchHTMLBody url = runErrorT $ runKleisli fetchHtmlA url
----------------------------------------------------------------------
xkcd = "http://xkcd.com/"

xkcdJSONUrl Current = xkcd ++ "info.0.json"
xkcdJSONUrl (ComicNumber n) = xkcd ++ show n ++ "/info.0.json"

xkcdFetchJSON :: ComicNumber -> IO (Either String String)
xkcdFet

Solution

Looks pretty good. You're getting on top of stuff nicely. Some criticism:

  • don't use package imports



  • write type signatures for top level functions



  • write comments!



  • thread design looks good.



  • don't use if'. Haskell has if already.



  • Kleisli needs documentation. Starting to go overboard at this point.



  • don't mix too many concepts in one program: the code won't be maintainable.

Context

StackExchange Code Review Q#2574, answer score: 11

Revisions (0)

No revisions yet.