Trying to put some order in ghci output

Viewed 62

For didactical purposes I am trying to follow and implement IO inside.

The idea is to express a type MIO a ("my IO") which is a RW -> (a, RW).

RW is the real world and, for the sake of simplicity, it's just an Integer; I cannot use the real RealWorld because there are no constructors around.

The first lines I've come up with are:

type RW = Integer

putString :: String -> RW -> ((), RW)
putString str world = (unsafePerformIO $ putStrLn str, world + 1)

getString :: RW -> (String, RW)
getString world = let input = unsafePerformIO getLine
  in (input, world + 1)

After that I try to define several ways to interact with the user, like asking one or more questions. The whole code is here.

Already starting from getString I get a very funny output:

*Main> getString 0
("This is my input
This is my input",1)
*Main>

I see the result of getString is correct, but the screen gets messy. Asking questions makes it even messier.

In the case of getString I wish the initial (" came together with the final result. Is it possible in ghci? (I doubt it, but I ask anyhow)

When I studied these same matters in JavaScript, things were easier because I could get popups for free from the browser. Is there some Haskell-ready environment where I could plug in my code?

I know that by using unsafePerformIO I have damned my soul to eternal sufferings, but reminding me that is gonna be beside my point.

1 Answers

Your problem is easily solved with some seq.

getString :: RW -> (String, RW)
getString world =
  let input = unsafePerformIO getLine
  in input `seq` (input, world + 1)

Behold:

λ getString 0
Hello!
("Hello!",1)

How cool is that?

But I want to also nudge you a bit beyond what you are asking: can you make your tuple a monad? (Hint: you will need to modify it in some way.) Then you could use do notation and your RW IO will look just like the real thing!

 

P.S. As @chi points out in a comment, you should rather prefer pseq when you wish to ensure order. There is a veritable wall written about it on Haskell Wiki.

Related