# Converting image size from Maybe (Int, Int) to (Float, Float)

I have a function that returns size of an image IO (Maybe (Int, Int)) It would be nice to convert it to float tuple beautifully.

I am sure there must be a better way than what I currently have:

data Vec2D = Vec2D Float Float

getImageSize :: FilePath -> IO (Maybe (Int, Int))
getImageSize path = do
case img of
Left _ -> return Nothing
Right img' -> return (go img')
where
go :: DynamicImage -> Maybe (Int, Int)
go (ImageRGB8 (Image w h _)) = Just (w, h)
go (ImageRGBA8 (Image w h _)) = Just (w, h)
go _ = Nothing

getImageSizeVec :: FilePath -> IO Vec2D
getImageSizeVec path = do
res <- getImageSize path
let dims = fromMaybe (0, 0) res
return $Vec2D (fromIntegral (fst dims)) (fromIntegral (snd dims))  ## 1 Answer 1. I do not understand what benefit you get from the conversion to float 2. I would advise you to not mix - IO with the mostly pure calculation you have so let us look at your code (minus the IO) getImageSize :: DynamicImage -> Maybe (Int, Int) getImageSize (ImageRGB8 (Image w h _)) = Just (w, h) getImageSize (ImageRGBA8 (Image w h _)) = Just (w, h) getImageSize _ = Nothing  but readImage already has a more useful return type than Maybe it has an Either String which is giving you error messages instead of Nothing so we can adjust. getImageSize :: DynamicImage -> Either String (Int, Int) getImageSize (ImageRGB8 (Image w h _)) = Right (w, h) getImageSize (ImageRGBA8 (Image w h _)) = Right (w, h) getImageSize _ = Left "Image type neither ImageRGB8 or ImageRGBA8"  this section could be improved a bit - also working on pure data sizeToVec :: (Int,Int) -> Vec2D sizeToVec (x,y) = Vec2D (fromIntegral x) (fromIntegral y)  you can then use those with the many mechanisms haskell provides you:  readImage path :: IO (Either String DynamicImage) getImageSize :: DynamicImage -> Either String (Int, Int) sizeToVec :: (Int,Int) -> Vec2D  the last two you can combine à la fmap sizeToVec (getImageSize img) -- or fmap sizeToVec . getImageSize  and the first two doStuff = do eitherImg <- readImg mypathtoimg return$ do size <- getImageSize
sizeToVec size


or

doStuff = do eitherImg <- readImg mypathtoimg
return (getImageSize eitherImg >>= sizeToVec)


or even shorter

doStuff = readImg mypathtoimg >>= (getImageSize >>= sizeToVec)

doStuff = readImg path >>= fmap sizeToVec . getImageSize

if I am not mistaken (I have no haskell env on this machine, therefore this code is untested - sorry)

• sizeToVec has the wrong type for >>=. Perhaps you meant readImg path >>= fmap sizeToVec . getImageSize?
– Zeta
Jan 17, 2016 at 15:27