Why not assign a type to unsafePerformIO?

One of the "holes" in real-world Haskell is you never know if a library/function is calling unsafePerformIO and you have to trust the library author. I recognize the necessity of the function, but should it announce itself? unsafePerformIO has this type: unsafePerformIO :: IO a -> a Would there be any value to making it have a type that can be stripped off, like some other monads? For example, providing a "runUnsafe" or similar: data UnsafePerformIO a = Unsafe a runUnsafe :: UnsafePerformIO a -> a runUnsafe (Unsafe o) = o and changing unsafePerformIO to have the type: unsafePerformIO :: IO a -> UnsafePerformIO a It seems it would be valuable to have functions announce when they use unsafePerformIO, but additionally allow it to be stripped off. So the classic launchMissiles :: a -- Uses unsafePerfomIO! Would become launchMissiles :: UnsafePerformIO a Which could be stripped off it you wanted: evilDictatator :: a evilDictator = runUnsafe $ launchMissiles But doesn't have to be: incompetentDictator :: a incompetentDictator = launchMissiles -- Doesn't type check! I doubt this is original - does it buy anything? Justin

On Wed, 2007-10-03 at 14:47 -0700, Justin Bailey wrote:
One of the "holes" in real-world Haskell is you never know if a library/function is calling unsafePerformIO and you have to trust the library author. I recognize the necessity of the function, but should it announce itself? unsafePerformIO has this type:
unsafePerformIO :: IO a -> a
Would there be any value to making it have a type that can be stripped off, like some other monads? For example, providing a "runUnsafe" or similar:
data UnsafePerformIO a = Unsafe a
runUnsafe :: UnsafePerformIO a -> a runUnsafe (Unsafe o) = o
and changing unsafePerformIO to have the type:
unsafePerformIO :: IO a -> UnsafePerformIO a
It seems it would be valuable to have functions announce when they use unsafePerformIO, but additionally allow it to be stripped off. So the classic
launchMissiles :: a -- Uses unsafePerfomIO!
Would become
launchMissiles :: UnsafePerformIO a
Which could be stripped off it you wanted:
evilDictatator :: a evilDictator = runUnsafe $ launchMissiles
But doesn't have to be:
incompetentDictator :: a incompetentDictator = launchMissiles -- Doesn't type check!
I doubt this is original - does it buy anything?
This already exists. The monad is called IO, the unsafePerformIO implementation is called id, and runUnsafe is called unsafePerformIO. I really don't see how another set of aliases buys anything. jcc

Hello Justin, Thursday, October 4, 2007, 1:47:00 AM, you wrote:
Which could be stripped off it you wanted:
evilDictatator :: a evilDictator = runUnsafe $ launchMissiles
just imagine using ByteString library with all these runUnsafe calls flying around :))) or using immutable arrays - in Hugs, they are implemented using unsafeIOToST. and the last point - because almost everything is based on using C calls and they *can* launch missiles, you should have *every* library function imported to be in these Unsafe monad. are you really need it? :D -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com
participants (3)
-
Bulat Ziganshin
-
Jonathan Cast
-
Justin Bailey