3

Is there a possible way to rewrite this in a single line through the use of Monads?

input <- getLine
let parsed = reads input :: [(Int,String)]

I could not understand how I can pass input, my attemp would be thinking about lambda notation.

piggyback
  • 9,034
  • 13
  • 51
  • 80

2 Answers2

7

Another place for fmap ! Use fmap to change a value or values inside something else - in this case, inside getLine, but it's more widely useful.

parsed <- fmap reads getLine :: IO [(Int,String)]

or with import Data.Functor or import Control.Applicative you could write this as

parsed <- reads <$> getLine :: IO [(Int,String)]

The compiler might well be able to deduce you mean Int from elsewhere, in which case you could omit the explicit type signature.

fmap is a very very useful function indeed to know. You could read more in this other answer about fmap where I ended up writing a mini tutorial.

Actually, if you're interested in clean ways of writing one-liners, then you should find out more about Applicative Functors.

Community
  • 1
  • 1
AndrewC
  • 32,300
  • 7
  • 79
  • 115
4

Sure, you can use liftM (or fmap, since IO also has a Functor instance) to have it on one line,

parsed <- (reads :: ReadS Int) `liftM` getLine

But I would argue that that rarely increases readability.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431