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

Haskell program to rename images based on EXIF data

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

Problem

Moved originally from StackOverflow, not knowing the existence of this sister site ...

Must say I find programming in Haskell to require much more cognitive intensity than any other language I've tried. I'm not certain I care about lazy evaluation or monads very much, but I do appreciate certain functional aspects, static type checking and not needing a huge VM to run.

I've been writing a short program to rename images based on EXIF and now have something that works. I'd like someone Haskell expert opinions on the overall structure of the source code in terms of what I've done right/wrong, and how I might improve and make the code more succinct. I won't bother posting the entire program but a lot of the overall structure is below.

```
import Control.Applicative
import Control.Monad.Error
import Data.Char
import Data.Either
import Data.List
import Data.Maybe
import Data.Time.Format
import Data.Time.LocalTime
import System.Console.GetOpt
import System.Directory
import System.Environment
import System.FilePath
import System.Locale
import System.IO.Error
import Text.Printf

import Album.Utils
import Album.Exif
import Album.Error

-- -----------------------------------------------------------------------
-- Main

main = do
r do
printf "Error type: %s\n" $ (show $ ioeGetErrorType err)
printf "Error string: %s\n" $ (ioeGetErrorString err)
printf "Error filename: %s\n" $ (maybe "None" id $ ioeGetFileName err)
printf "Error handle: %s\n" $ (maybe "None" show $ ioeGetHandle err)
Right _ -> return ()

-- Process arguments
main0 = do
args showUsage usage
(False, (flags, fns, []), usage) -> do
rv showErrs [show e] usage) (const $ return ()) rv
(False, (_, _, errs), usage) -> showErrs errs usage
where
desc = "Rename and catalog media.\n" ++
"Usage: album -n \n"

-- Sanity check
main1 flags fns = do

-- Check name
albName (n, exifToDateTime e)) exifs
let nodates = filter (isNothing . snd)

Solution

I'm definitely not a Haskell expert, but here are my 2 cents:

  • You should break your main functions in several methods. The amount of code running inside the IO monad should be minimized.



  • You often use case ... of where a separate function with pattern matching would be more readable



  • albumName could use a fold

Context

StackExchange Code Review Q#3310, answer score: 2

Revisions (0)

No revisions yet.