Brandon S. Allbery KF8NH wrote: > > On Oct 15, 2007, at 13:32 , Peter Verswyvelen wrote: > >> [EMAIL PROTECTED] wrote: >>>> Yes, *different approach*. So, there *are* differences. Compilers, >>>> anyway, >>>> are special applications. I wanted to see - responding to Brandon - a >>>> "normal" Haskell program, which does IO without monads, that't all. >>>> The problem is then when you hide something, you hide. It is >>>> possible to >>>> superpose a kind of monadic framework on unique worlds, files, etc. in >>>> Clean, but the reverse operation goes beyond my horizons. >>>> Some examples, anybody? >> Ah yes, I see what you mean now. I have no idea, I guess only >> unsafePerformIO will allow you to do something like that... But that >> will completely break referential transparency. But I really don't >> know. What do the experts have to say? > > Use the source of unsafePerformIO as an example of how to write code > which passes around RealWorld explicitly, but without unencapsulating it > like unsafePerformIO does. > > The main problem here, I think, is that because all the GHC runtime's > functions that interact with RealWorld (aside from unsafe*IO) are > themselves only exported wrapped up in IO, you can't (as far as I know) > get at the lower level internal (e.g.) putStrLn' :: RealWorld -> String > -> (# RealWorld,() #) to do I/O in a direct/explicit/non-monadic style. > In theory, one could export those and use them directly.
Well, if you import GHC.IOBase then you get > newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #)) > > unIO :: IO a -> (State# RealWorld -> (# State# RealWorld, a #)) > unIO (IO a) = a Then the type of putStrLn: -- putStrLn :: String -> IO () means that putStrLn' can be defined as putStrLn' :: String -> State# RealWorld -> (# State# RealWorld, a #) putStrLn' = unIO . putStrLn Now you have the unboxed tuple and need to work with many 'case' statements to accomplish anything. Also you need to get you hand on State# RealWorld either (1) Honestly, by wrapping your code in IO again and using it normally (2) From a copy, via unsafeInterleaveIO (3) From nowhere, via unsafePerformIO > > (Actually, as a practical matter, IIRC GHC "knows about" RealWorld and > removes all of it when generating cmm code once it's done the job of > sequencing Haskell evaluation; I'm not sure how well that would work if > you wrote I/O in direct/explicit style. unsafePerformIO doesn't really > count for that because it removes the RealWorld itself.) > _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe