fixST is a bit wrong
Lazy blackholing lets some ST calculations complete that shouldn't.
import Control.Monad.ST.Strict
import Control.Monad.Fix
import Data.STRef
foo :: ST s Int
foo = do
ref <- newSTRef True
mfix $ \res -> do
x <- readSTRef ref
if x
then do
writeSTRef ref False
return $! (res + 5)
else return 10
main = print $ runST foo
When this is compiled with -O -feager-blackholing, it produces a <<loop>> exception as expected. When it's compiled with -O0 or with -fno-eager-blackholing, it prints 15.
Should we reimplement fixST to do something like what fixIO does? Or should we consider this sometimes-lost bottom tolerable?
Trac metadata
| Trac field | Value |
|---|---|
| Version | 8.5 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Core Libraries |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | simonmar |
| Operating system | |
| Architecture |