Skip to content

unsafePerformIO in fromInteger causes loops

Summary

When creating a Num instance using unsafePerformIO the IO action seems to be repeated forever instead of being executed once. Even if the io is just (return 5) the program stalls. If -O2 is used the loop is detected and it prints <>.

Steps to reproduce

The following code is a minimal example:

import System.IO.Unsafe

data Retarded =  Retarded deriving Show -- to be clear I called it Retarded to poke fun at using unsafePerformIO in fromInteger not to insult the compiler

instance Num Retarded where
  fromInteger _ = unsafePerformIO (putStrLn "good god why does this loop" >> return 5)

main :: IO ()
main = print (42 :: Retarded)

Expected behavior

What do you expect the reproducer described above to do? print "good god why does this loop"" once then print 5. I was also kind of hoping that the compiler would evaluate literals at compile time, and thus I could get the compiler itself to print something.retarded.hs

Environment

  • GHC version used: 8.6.5

Optional:

  • Operating System: void linux
  • System Architecture: x86_64
Edited by Ben Gamari
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information