|
Smoke_Max posted:Hi, Haskell newbie here. I was wondering why main doesn't have a [String] -> IO () type signature like other programming languages, like C/C++ or Java. It would be pretty cool, thanks to pattern matching, to be able to do things like this: This idea is pretty close to what main's signature actually is, if you imagine "IO a" to mean "World -> (a, World)", where World is the type of the rest of the universe. The main function takes a World, emits a value, and also yields a new World, just like other IO actions. Composing IO actions together amounts to threading successive World states through the calls. Unspecified system magic takes care of providing the initial World to the main function at startup. Part of the World is the arguments provided to the program. These are accessible not just in main, but anywhere that we have access to a World. Alternatively, it could make sense to split them off, so main had effective type [String] -> World -> ((), World); and then the arguments could be passed around explicitly wherever they were needed. Or the arguments could be provided as some global constant "args :: [String]", without even an IO type. (For example, this happens with System.Info.os :: String, since we expect the operating system name to be constant over the running life of the program). It so happens that Haskell decided to treat program arguments as part of the World. Now, we don't actually have access to World values for a few related reasons. One is that the design of IO as an opaque type allows implementers to not have to provide Worlds as a collection of state - IO can be implemented in other ways, much more conveniently. Also, if we could inspect World values, then we could do things which IO is designed to forbid, like saving World copies for later. So all the "get state from the system" style of actions ultimately need to make use of some builtin special functions to do the work, and have an IO type in order to achieve the proper sequencing of actions. The getArgs function is like this; with type "IO [String]" it is as if there is a World coming in (to pull some Strings from), which is provided by some call chain, within the IO monad, up to the initial state of the World provided to main. Another trick, by the way, is: code:
|
# ¿ Jun 4, 2015 01:43 |
|
|
# ¿ Apr 28, 2024 04:46 |