On Oct 15, 2007, at 19:00 , ChrisK wrote:
Brandon S. Allbery KF8NH wrote:
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
(4) Honestly but unwrapped, by defining "main" in the same desugared
way (takes State# RealWorld and returns (# State# RealWorld,a #) (or
(# State# RealWorld,() #) if you stick to the H98 definition of
main's type), allowing the runtime to pass it in and otherwise not
doing anything other than propagating it.
My real problem was that I incorrectly recalled IO's type to be based
on ST, not State (i.e. had a forall to prevent anything from being
able to do anything to/with the State# RealWorld other than pass it
on unchanged without triggering a type error). I should have
realized that was wrong because unsafePerformIO is itself expressible
in Haskell (-fglasgow-exts is needed to make # an identifier
character and to enable unboxed types and unboxed tuples, but does
not make it possible to cross an existential type barrier).
--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED]
system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED]
electrical and computer engineering, carnegie mellon university KF8NH
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe