Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concatenate String and IO Integer in Haskell

I wrote a function returning the current screen width as IO Integer (working so far).

getScreenWidth:: IO Integer
getScreenWidth = do
                    (sx, sy, w, h) <- getScreenDim 0
                    return $ sx

Now I would like to add the screen width to a string:

> magic_function :: IO Integer -> String -> ... magic output type
> magic_function = ... ? this is where i am stack at ? ...

I would like to pass the magic function to a string, something like "Screen Width: " and i want it to add the current screen width, so that i get "Screen Width: 1680". How can i concat an IO Integer and a common String? Does it work with show?

Could anyone help me with that?

like image 648
Monkeyphant Avatar asked Sep 15 '26 17:09

Monkeyphant


2 Answers

First, forget about the IO:

labelInteger :: String -> Integer -> String
labelInteger label number = label ++ ": " ++ show number

Now worry about the IO:

import Control.Monad (liftM, liftM2)

labelIOInteger :: String -> IO Integer -> IO String
labelIOInteger label ioNumber = liftM (labelInteger label) ioNumber

Use as e.g. labelIOInteger "Screen Width" getScreenWidth... but beware! If you do something like this:

widthLabel <- labelIOInteger "Screen width" getScreenWidth
isPortrait <- liftM2 (<) getScreenWidth getScreenHeight

...then getScreenWidth will be executed twice... which admittedly for this particular action is unlikely to be a problem, but if it was an action that read an integer from a file or a database or a website, you can see that executing it twice might be undesirable.

It is usually better not to write functions like labelIOInteger, and instead do this:

widthLabel <- liftM (labelInteger "Screen Width") getScreenWidth

...so that if you find yourself needing to use the return value for two different calculations, you can easily refactor to this:

screenWidth <- getScreenWidth
let widthLabel = labelInteger "Screen Width" screenWidth
isPortrait <- liftM (screenWidth <) getScreenHeight
like image 194
dave4420 Avatar answered Sep 17 '26 13:09

dave4420


magic_function :: IO Integer -> String -> IO String
magic_function num msg = do
                            n <- num
                            return (msg ++ (show n))
like image 35
Ankur Avatar answered Sep 17 '26 12:09

Ankur