Home > Software engineering >  Create an IO string
Create an IO string

Time:04-08

For some reason getLine is not working in my Jupiter notebook. Is there any way to create artificially an IO string so I can continue with some examples that need that?

I tried something like this:

main = do
    foo :: IO String
    foo << "sdf"
   

But didn't work obviously. Any way to do that? Thanks!

CodePudding user response:

A value of type IO String represents an action that may do some IO and produce a String if it’s executed (ultimately, from main). Normally, getLine is such an action that reads a line of text from “standard input” (stdin). If you just want to make your own action to use instead of getLine, you can construct one quite simply using pure :: (Applicative f) => a -> f a where f is IO and a is String in this case:

fakeGetLine :: IO String
fakeGetLine = pure "always the same string"

Aside: pure is also called return :: (Monad m) => a -> m a for historical reasons, but there’s no need to use it, since it’s the same function with a longer name and a slightly more restricted type.

Now, anywhere you would’ve entered getLine, you can replace it with fakeGetLine, or an expression such as pure "whatever string you wish to use". Likewise, if you needed a constant IO Int, you could use pure 123 or pure (123 :: Int).

You can’t replace the standard getLine, but it is possible to use your own definition with the same name of getLine, provided that you hide the default one from scope using an importhiding declaration:

import Prelude hiding (getLine)

getLine :: IO String
getLine = pure "always the same string"

Alternatively, you can in fact read from stdin in an IPython notebook, as long as you open it with a frontend that supports the “input request” feature, such as JupyterLab or Deepnote. To the best of my knowledge, this is not currently supported in Hydrogen, nteract, or Spyder.

Finally, a method sometimes recommended for this issue in Python, which will not work in Haskell, is attempting to replace stdin with a different handle. That technique is possible in Python because its stdin is a mutable variable, while in Haskell, stdin (like all variables) is immutable.

  • Related