[Haskell-cafe] Using unsafePerformIO safely

Hector Guilarte hectorg87 at gmail.com
Wed Jun 24 18:35:14 EDT 2009


Hello,

I made a GCL compiler using Alex and Happy and now I'm making the
interpreter to that program. Here's the deal:

First of all, I'm no expert in the usage of monads. Now:

Whenever a "show" instruction is found in any GCL program while the
interpretation is being done it is supposed to print on the stdout the
string or the aritmetic expresion it was called with, so I guessed I need to
run an IO operation and continue the interpretation of my program. I managed
to do this using unsafePerformIO and `seq` like is shown below. My question
is: Is it safe to use it this way? So far it is working great, but I need to
be sure I'm using it in a "safe" way. Like I said, I'm no expert in monads
and the System.IO.Unsafe documentation says:

"

*unsafePerformIO* ::
IO<http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AIO>a
-> a
This is the "back door" into the
IO<http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AIO>monad,
allowing
IO<http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AIO>computation
to be performed at any time. For this to be safe, the
IO<http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AIO>computation
should be free of side effects and independent of its
environment.
"

I don't know if the IO computation I'm doing is free of side effects and
independent of its enviroment :s. (is just hPutStr stdout ....)

Also I've read something about my code not being executed for sure or
something like that. Can somebody check the code and tell me if I'm "safe"
with it?

Thanks a lot!

Here's the code:

-- Tabla is my Symbol Table of the program being interpreted
evalInstruccion:: Instruccion -> Tabla -> Tabla
evalInstruccion (ShowY showY) tabla = myRunIO (evalShow showY tabla)
evalInstruccion _ tabla = tabla      -- There are many other Instructions
here missing wich are not relevant to my question

{-# NOINLINE myRunIO #-}
myRunIO:: (Tabla, IO()) -> Tabla
myRunIO tupla = ((unsafePerformIO (snd tupla)) `seq` (fst tupla)) -- Here's
the unsafePerformIO.... Am I safe?

evalShow:: ShowY -> Tabla -> (Tabla, IO())
evalShow (ShowS string) tabla = (tabla,(hPutStr stdout string))
evalShow (ShowE expr) tabla = (tabla,(hPutStr stdout (show (evalExpr expr
tabla)))) -- Don't worry about evalExpr, it works and returns an Int
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090624/004b0e3c/attachment.html


More information about the Haskell-Cafe mailing list