Created
July 25, 2011 23:02
-
-
Save niuk/1105485 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
main : IO () | |
open : IO Handle | |
write : Handle -> String -> IO () | |
close : Handle -> IO () | |
main = do | |
fd <- open "log.txt" | |
write fd "Hello World!" | |
close fd | |
# this desugars to: | |
main = | |
open "log.txt" >>= \fd -> | |
write fd "Hello World!" >>= () -> | |
close fd | |
# if we model the (IO t) monad as a function that takes an opaque RealWorld value | |
# and returns a pair (t, RealWorld), then the above would turn into: | |
main world = | |
(\(fd, world) -> | |
(\((), world) -> | |
(close fd world) | |
) (write fd "Hello World!" world) | |
) (open "log.txt" world) | |
# The key here is aggressive inlining. The bind operator (>>=), due to its | |
# simple operation, should expand within the body of its caller if it is | |
# saturated, that is, if both of its arguments are immediately given. | |
# RealWorld is actually just a dummy; it does not take up any space in memory, | |
# so we can pretend that we are only passing the "important" values around, | |
# and that the IO functions can be called "raw": | |
main = | |
(\fd -> | |
(\() -> | |
(close fd) | |
) (write fd "Hello World!") | |
) (open "log.txt") | |
# Note that the two anonymous functions here are applied immediately. They | |
# are not returned, passed as arguments, or even given names. Thus, the | |
# compiler knows that the above can be transformed into: | |
main = | |
let fd = open "log.txt" in | |
let () = write fd "Hello World!" in | |
close fd | |
# Inlining is, again, key to this transformation. In general, lambdas that | |
# are "used up" immediately are equivalent to a let-block. At this point, | |
# translation into C (or LLVM) should be obvious: | |
main() { | |
int fd = open("log.txt"); | |
write(fd, "Hello World!"); | |
close(fd); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment