Am I abusing unsafePerformIO?

前端 未结 4 1072
天命终不由人
天命终不由人 2020-12-28 14:25

To get acquainted with unsafePerformIO (how to use it and when to use it), I\'ve implemented a module for generating unique values.

Here\'s what I have:

4条回答
  •  佛祖请我去吃肉
    2020-12-28 14:54

    See an another example how this fails:

    module Main where
    import Unique
    
    helper :: Int -> Unique
    -- noinline pragma here doesn't matter
    helper x = newUnique ()
    
    main = do
      print $ helper 3
      print $ helper 4
    

    With this code the effect is the same as in ntc2's example: correct with -O0, but incorrect with -O. But in this code there is no "common subexpression to eliminate".

    What's actually happening here is that the newUnique () expression is "floated out" to the top-level, because it doesn't depend on the function's parameters. In GHC speak this is -ffull-laziness (on by default with -O, can be turned off with -O -fno-full-laziness).

    So the code effectively becomes this:

    helperworker = newUnique ()
    helper x = helperworker
    

    And here helperworker is a thunk that can only be evaluated once.

    With the already recommended NOINLINE pragmas if you add -fno-full-laziness to the command line, then it works as expected.

提交回复
热议问题