I wrote a function in haskell that takes a few parameters like Word32, String (ignore currying) and outputs IO Word32. Now, this is a function in the true sense: for the same inputs, the output will always be the same. There are no side-effects. The reason the function returns IO Word32 instead of Word32 is that the function updates many 32 bit Linear Feedback Shift registers (lfsr) and other registers several times in a loop in order to compute the final Word32 output.
My question is this: Given that this function effectively has no side-effects, is it possible to hide those register updates inside the function implementation so that the function returns Word32 and not IO Word32? If so, how?
IORef
s to hold LSFRs? Maybe you should consider usingSTRef
instead and run the computation inside anST
monad. – CarmacarmackIO
is normally when evaluating(>>=)
applied to that value in a subexpression ofmain
. WithunsafePerformIO
, I think the side effects trigger whenever the thunk holding the value is forced, an event invisible to the code itself, and are subject to being rearranged at will by GHC's optimizer in ways that can change both the ordering and number of times the side effects occur. – AlciniaRealWorld
. Each (ordinary) IO action is strict in this token and only returns anything, when the IO is finally done. There is no magic involved. It's just that the evaluation order is forced by the use of a token. You can manually deconstruct IO values and juggle with their tokens - than the compiler happily changes their order. (See for instance here) – EricksonunsafePerformIO
works similiar - the IO operation passed to the function becomes deconstructed. Then they pass a new token to it and drop the resulting token - that's all what is needed to do unsafe IO. – EricksonrunST
does. And no,IO
is not "just" a state monad, unless you think theRealWorld
token actually contains the state of the entire outside universe, and that nothing in the universe changes until the token is returned. – AlciniaRealWorld
is of course just a dummy token that represents the whole universe. It's just a convenient way to implement IO. Hm... I don't wanted to start such an argument. In the beginning, I just wanted to say, that there is nothing special with IO. The ordering is defined via clever use of the haskell semantics. – Erickson