문제

I'm a complete newbie currently trying to learn Haskell with "Learn You a Haskell for Great Good". I've reach the section explaining how to work with command line arguments, and something is bugging me.

From my understanding (and haskell.org's definition), actions are meant to encapsulate side effects. Command line arguments being immutable inputs for a given instance of the program, then what is the point of having getProgName :: IO String rather than getProgName :: String? Differently put: what's the point of preventing a pure function from calling getProgName?

Update

I had some great answers to this question so far. I'm accepting Don Stewart's as the most simple and concise, but Conal's (with its associated blog post) is definitely worth a read.

도움이 되었습니까?

해결책

Firstly, getArgs can change at runtime. See withArgs.

Secondly, getArgs and getProgName fall into an interesting class of impure computations - they are thought of as constants during a program run, however, they're are not values available at compile time, and they change from one program run to another. They don't have a clean denotation.

See e.g. earlier discussions, where getArgs, and floating point computations are discussed. And even minBound/maxBound can be thought to be in this class.

다른 팁

To answer such questions, you'll need a foundation: what does it mean that an expression e has type t? You could give arbitrary answers for primitives like getProgName, but you don't have to. Instead, look at the meanings of expressions and of types. Say that an expression e has type t when the value denoted by e (i.e., the meaning of e as a mathematical value) belongs to the collection denoted by t.

Now consider t == String. What meaning do we want String to have? Again, there's a lot of room for choice here. However, there's a lot of merit in choosing the useful candidate with the simplest mathematical definition. In Haskell String == [Char], so we're really talking about the meanings of [] and Char The most compelling simple candidates I know of are that [] denotes lists (sequences), and Char denotes characters, and consequently that String denotes sequences of characters, i.e., "strings".

With the choice that String means strings, now we're in a position to ask whether it's possible that getProgName :: String. If so then the meaning of getProgName must be a sequence of characters. However, there is no single sequence of characters that captures the intent behind getProgName. (Edit: Presumably, you want getProgName to yield different strings when it appears in differently-named programs.) Therefore, we have to either choose a different type, such as (but not necessarily) IO String, or we have to choose a more complicated meaning for String. The latter route might at first seem appealing, until you consider the deep implications. Purely functional (more accurately "denotative") programming supports practical, rigorous reasoning thanks to using simple meanings like sequences rather than complex meanings like functions from some sort of environment including operating system, machine execution context.

For closely related remarks and discussion, see the blog post Notions of purity in Haskell.

Edit: I think Peter Landin (grandfather of Haskell) expressed it best with his definition of "denotative programming" (or "genuinely functional programming"), which he recommended as a substantive replacement to vague terms like "declarative" and "functional" programming. For a reference, quotations, and brief commentary, see this comment in the post Is Haskell a purely functional language?.

My understanding is pure functions are pure because you can reason with them at "code time", and the compiler can, at compile time. IO actions are runtime dependent. getArgs, which gives arguments to a program only when it is run, is hence an IO action.

As Learn you a Haskell puts it:

You can think of an I/O action as a box with little feet that will go out into the real world and do something there (like write some graffiti on a wall) and maybe bring back some data.

We don't know what the box with little feet will bring in at code time or compile time.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top