0

So, I want to rewrite the given prog function with using >>/>>= bindings instead of do and <- :

prog :: IO Int
     prog =
       do putStrLn "Hello there! How old are you?"
       age <- (readLn :: IO Int)
       let agedays = show $ age * 365
       putStrLn $ "So you are at least than " ++ agedays ++ " days old."
       return (read agedays)

Rewriting more simple functions is not a problem for me, but the readLn :: IO Int is giving me a headache...

My suggestion was:

prog :: IO Int
prog =
     putStrLn "Hello there!How old are you?" >>
     readLn::IO >>=
     let agedays = \age -> show $ age * 365 >>
     putStrLn $ "So you are at least than " ++ agedays ++ " days old."

However this just does not work, as there is a problem with binding the readLn :: IO to the next anonymous function \age. Any help?

Will Ness
  • 70,110
  • 9
  • 98
  • 181
ArdianH101
  • 55
  • 5

2 Answers2

5

You are changing the code too much, e.g. removing Int from IO Int, and inserting lambdas in the wrong points.

Something like this should work:

prog =
   putStrLn "Hello there! How old are you?" >>
   (readLn :: IO Int) >>= \age ->
   let agedays = show $ age * 365
   in putStrLn $ "So you are at least than " ++ agedays ++ " days old." >>
   return (read agedays)
chi
  • 111,837
  • 3
  • 133
  • 218
4

You can let the type inference do the work for you,

prog :: IO Int
prog =
     putStrLn "Hello there! How old are you?" >>
     readLn >>= (\ age ->
     let agedays = age * 365 in
       putStrLn ("So you are at least " ++ show agedays ++ " days old.") >>
       return agedays )

Since you already specify prog :: IO Int, it means return agedays :: IO Int, and agedays :: Int.

Then, both operands to * in age * 365 must be of the same type, specifically, that of agedays, since we have agedays = age * 365 there. Thus it follows that age :: Int already.

Will Ness
  • 70,110
  • 9
  • 98
  • 181