What is the difference between IO () and IO? - haskell

There are two different ways of using IO in haskell programs, for example:
main :: IO ()
-- and
readLine :: IO Int
What is the difference between these two?

IO () and IO Int are fundamentally very similar. Int and () are both types in Haskell. () is special only in the sense that it has only one value ( also denoted by () ), so we're never really interested in it.

The only difference is their return value. main returns a value of type () and your readLine returns an Int. Perhaps this example will help:
main = do
x <- putStrLn "Test"
print x
When you run it, it outputs:
>>> main
Test
()
The print statement prints a () because that is the return value of putStrLn:
putStrLn :: String -> IO ()
The reason you normally don't bind the return value of something like putStrLn is that there is no information gained from doing so, since it always returns () no matter what.

IO () is the type of an action that can be executed to extract a value of type (). There is only one (non-bottom) value of type (), which is also spelled () (you tell them apart by knowing whether you're looking at a type expression or a value expression, just as names starting with an uppercase letter are either type constructors or data constructors, depending on whether you're looking at a type expression or a value expression). Since there is only one (non-bottom) value, the value tells you absolutely nothing (strictly speaking it does at least tell you that the computation did terminate successfully, but that's all). So IO () is usually used as the type of IO actions that we're only interested in for their side-effects.
putStrLn "Hello World" is an example of a value of type IO (). It doesn't compute anything at all interesting; what is the value resulting from having written a string to the terminal? Getting the () when it's executed only tells us that it did indeed execute.
IO Int is the type of an action that can be executed to extract a value of type Int. As with all IO actions, what exactly it does can have effects on and be affected by the world outside the program; Haskell knows nothing about them. But it does know that executing the action will result in a Haskell value of type Int, regardless of whatever else it might do.
readLn :: IO Int is an example of a value of type IO Int (the type annotation is necessary as a standalone expression to avoid ambiguity; in a wider context where you actually use the value extracted from readLn for some Int-specific operations you could probably leave it off). Unlike writing a string to the terminal, reading a string from the terminal and converting it to an Int does result in a value.
More generally IO is a type constructor that can be applied to any type; IO a is the type of an execution that could be executed and would result in a value of type a. Both of the above are just examples of this; neither is handled specially. () is a perfectly ordinary type, and () is a perfectly ordinary value of that type, but because such values don't convey any information (other than "this computation successfully terminated") you don't normally see () on its own; it tends to be used only with type constructors applied, such as in IO (), for values where we care only about the structure added by the type constructor, not about the values "inside" it.

IO Int means: this is an IO action that returns an Int.
IO () means: this is an IO action that doesn't return any meaningful result. (like main.)

Related

Is print in Haskell a pure function?

Is print in Haskell a pure function; why or why not? I'm thinking it's not, because it does not always return the same value as pure functions should.
A value of type IO Int is not really an Int. It's more like a piece of paper which reads "hey Haskell runtime, please produce an Int value in such and such way". The piece of paper is inert and remains the same, even if the Ints eventually produced by the runtime are different.
You send the piece of paper to the runtime by assigning it to main. If the IO action never comes in the way of main and instead languishes inside some container, it will never get executed.
Functions that return IO actions are pure like the others. They always return the same piece of paper. What the runtime does with those instructions is another matter.
If they weren't pure, we would have to think twice before changing
foo :: (Int -> IO Int) -> IO Int
foo f = liftA2 (+) (f 0) (f 0)
to:
foo :: (Int -> IO Int) -> IO Int
foo f = let x = f 0 in liftA2 (+) x x
Yes, print is a pure function. The value it returns has type IO (), which you can think of as a bunch of code that outputs the string you passed in. For each string you pass in, it always returns the same code.
If you just read the Tag of pure-function (A function that always evaluates to the same result value given the same argument value(s) and that does not cause any semantically observable side effect or output, such as mutation of mutable objects or output to I/O devices.) and then Think in the type of print:
putStrLn :: String -> IO ()
You will find a trick there, it always returns IO (), so... No, it produces effects. So in terms of Referential Transparency is not pure
For example, getLine returns IO String but it is also a pure function. (#interjay contribution), What I'm trying to say, is that the answer depends very close of the question:
On matter of value, IO () will always be the same IO () value for the same input.
And
On matter of execution, it is not pure because the execution of that
IO () could have side effects (put an string in the screen, in this
case looks so innocent, but some IO could lunch nuclear bombs, and
then return the Int 42)
You could understand better with the nice approach of #Ben here:
"There are several ways to explain how you're "purely" manipulating
the real world. One is to say that IO is just like a state monad, only
the state being threaded through is the entire world outside your
program;= (so your Stuff -> IO DBThing function really has an extra
hidden argument that receives the world, and actually returns a
DBThing along with another world; it's always called with different
worlds, and that's why it can return different DBThing values even
when called with the same Stuff). Another explanation is that an IO
DBThing value is itself an imperative program; your Haskell program is
a totally pure function doing no IO, which returns an impure program
that does IO, and the Haskell runtime system (impurely) executes the
program it returns."
And #Erik Allik:
So Haskell functions that return values of type IO a, are actually not
the functions that are being executed at runtime — what gets executed
is the IO a value itself. So these functions actually are pure but
their return values represent non-pure computations.
You can found them here Understanding pure functions in Haskell with IO

IO Monads: GHC Implementation Meaning vs. Mathematical Meaning

Consider
ioFunction :: String -> IO ()
ioFunction str = do putStrLn str
putStrLn "2"
Here, ioFunction, from a mathematical point of view, is a function that takes one input and returns a value of type IO (). I presume it means nothing else. That is, from a mathematical point of view, this function returns a value and nothing else; in particular, it doesn't print anything.
So does this mean that the way Haskell uses the IO monad for imperative side-effects (in this case: that running this function will first print str and then print "2", in that order) is purely a GHC implementation detail that has nothing to do with the mathematical (and in some sense even the Haskell) meaning of the term?
EDIT: To make this question clearer, what I mean to ask is, for example, is there any difference from the mathematical point of view between the following two functions:
ioFunction1 :: String -> IO ()
ioFunction1 str = do putStrLn str
putStrLn "2"
ioFunction2 :: String -> IO ()
ioFunction2 str = do return ()
It seems the answer is no, for -- from the mathematical point of view -- they both take as input a String and return a value (presumably, the same value) of type IO (). Is this not the case?
Here, ioFunction, from a mathematical point of view, is a function that takes one input and returns a value of type IO (). I presume it means nothing else.
Yes. Exactly.
So does this mean that the way Haskell uses the IO monad for imperative side-effects (in this case: that running this function will first print str and then print "2", in that order) is purely a GHC implementation detail that has nothing to do with the mathematical (and in some sense even the Haskell) meaning of the term?
Not quite. From a mathematical (set-theory) standpoint, I would assume "same" means structurally identical. Since I don't know what makes up a value of IO (), I can't say anything about whether two values of that type are the same or not.
In fact, this is by design: by making IO opaque (in the sense that I don't know what constitutes an IO), GHC prevents me from ever being able to say that one value of type IO () is equal to another. The only things I can do with IO is exposed through functions like fmap, (<*>), (>>=), mplus, etc.
I always find it helpful to consider a simplified “imperative-language source code” implementation of the IO monad:
data IO :: * -> * where
PutStr :: String -> IO ()
GetLine :: IO String
IOPure :: a -> IO a
IOSeq :: IO a -> IO b -> IO b
...
LaunchMissiles :: IO ()
Then what ioFunction is quite clearly a proper, sensible function in the mathematical sense:
ioFunction str = do putStrLn str
putStrLn "2"
= putStr (str++"\n") >> putStrLn "2\n"
= IOSeq (PutStr (str++"\n")) (PutStrLn "2\n")
This is simply a data structure representing effectively some source code of an imperative language. ioFunction places the given argument in a specific spot in the result structure, so it's mathematically very much not just a trivial “return () and nothing else (something may happen but it's a GHC implementation detail)”.
The value is indeed completely different for ioFunction2:
ioFunction2 str = do return ()
= return ()
= IOPure ()
how do we know they are different in this sense?
That's a good question. Practically speaking, you know it by executing both programs and observing that they cause different effects, hence they must have been different. This is more than a little awkward of course – “observing what happens” isn't maths, it's physics, and the observation would scientifically require that you execute twice under exact the same environment conditions.
Worse, even with pure values that are generally taken to be mathematically the same you can observe different behaviour: print 100000000 will immediately cause the side-effect, whereas print $ last [0..100000000] takes a significant pause (which, if you follow it with a time-printing command, can actually yield different text output).
But these issues are unavoidable in a real-world context. It hence makes only sense that Haskell's does not specify any structure on IO that could with mathematical rigour be checked for equality from within the language. So, in quite some sense you really can't know that putStrLn str >> putStrLn "2" is not the same as return ().
And indeed they might be the same. It is conceivable to make a even simpler toy implementation of IO than the above thus:
data IO :: * -> * where
IONop :: IO ()
IOHang :: IO a -> IO a
and simply map any pure output operation to the no-op (and any input to an infinite loop). Then you would have
ioFunction str = do putStrLn str
putStrLn "2"
= IONop >> IONop
= IONop
and
ioFunction2 str = return ()
= IONop
This is a bit as if we've imposed an additional axiom on the natural numbers, namely 1 = 0. From that you can then conclude that every number is zero.
Clearly though, that would be a totally useless implementation. But something similar could actually make sense if you're running Haskell code in a sandbox environment and want to be utterly sure nothing bad happens. http://tryhaskell.org/ does something like this.
For simplicity, let us concentrate on the output aspect of the I/O monad. Mathematically speaking, the output (writer) monad is given by an endofunctor T with T(A) = U* × A, where U is a fixed set of characters, and U* is the set of strings over U. Then ioFunction : U* → T (), i.e. ioFunction : U* → U* × (), and ioFunction(s) = (s++"\n"++"2\n", ()). By contrast, ioFunction2(s) = ("", ()). Any implementation has to respect this difference. The difference is primarily a mathematical one, not an implementation detail.

pure code and impure code? I/O data type related [duplicate]

This question already has answers here:
In what sense is the IO Monad pure?
(9 answers)
Closed 7 years ago.
name <- getLine
The following paragraph is about how the line works. Can someone explain to me what this means? Thank you in advance.
getLine is in a sense impure because its result value is not
guaranteed to be the same when performed twice. That's why it's sort
of tainted with the IO type constructor and we can only get that data
out in I/O code. And because I/O code is tainted too, any computation
that depends on tainted I/O data will have a tainted result.
When I say tainted, I don't mean tainted in such a way that we can
never use the result contained in an I/O action ever again in pure
code. No, we temporarily un-taint the data inside an I/O action when
we bind it to a name. When we do name <- getLine, name is just a
normal string, because it represents what's inside the box.
The paragraph hints to the fact that you can't use getLine in a function which has a "pure" type, without the IO monad occurring in it. E.g. if we try to run
lineLength :: Int -> Int
lineLength n = n + length getLine
the compiler will complain because length expects a String (or any other list type) but getLine is an IO String. So there's a type mismatch.
But this does not mean that length and getLine can not be composed: here's how
lineLength :: Int -> IO Int
lineLength n = do
line <- getLine
return (n + length line)
Above we temporarily "remove the IO" since line :: String, so that length can be applied to it, and n added to the result. However, then we are forced to use return to transform a pure Int result into an IO Int.
Notice how the IO also ends up in the function signature: this is unavoidable.
In Haskell, if a function does impure things such as using IO, then the type system forces you to use IO in the type. This is the "taint" the quote is referring to: once you use an impure function/value with an IO type, then you have to use IO in the type of your own code, and any caller of that in turn will have to use IO. Impurity must be propagated in the type signatures.
This also means that if you see f :: Int -> Int, you can rely one the fact that the compiler proved the function to be pure: it will return the same result for the same input. (There are a few low-level ways to circumvent this, but they are not meant to be used in regular code.)

Expected Type and Main

Total Haskell noob here. I have a simple function, and a main. I don't have any idea what this error means:
Couldn't match expected type `IO t0' with actual type `Bool'
In the expression: main
When checking the type of the function `main'
when compiling the code:
is_instructor :: String -> Bool
is_instructor "Jeremy Erickson" = True
is_instructor x = False
main :: Bool
main = is_instructor "foo"
main is the thing that gets called when you run your programme. It is expected that a programme does in some way interact with the outside world (read input, print output, such things), therefore it's reasonable that a main should have the type IO something. For reasons of type safety and simplicity, that is a requirement in Haskell, like main in Java must have type public static void main(String[] arrgh).
You probably wanted you value to be printed, so
main :: IO ()
main = print $ is_instructor "foo"
would be what you want.
You can't have a main function with type Bool, it always needs to be in the IO monad. What you probably want is something like printing out this boolean value. Then just do that!
main :: IO()
main = print $ is_instructor "foo"
You've certainly heard that Haskell is a purely functional language. This means (among other things) that the only thing that a function can do in Haskell is compute a result that depends on the arguments; a function can't do I/O, or have a result that depends on something other than the arguments' values.
But Haskell allows you to write programs that do I/O and other effectful things. How is this possible? Well, what it means is that in Haskell, things that perform I/O or side effects are not functions; they are something else. People often refer to them as actions. I/O actions in Haskell have types of the form IO a.
The error you're getting here is that main, the entry point to a Haskell program, is required to be an action of type IO (). But is_instructor is a function of type String -> Bool, and is_instructor "foo" is a Bool.
Haskell doesn't allow you mix and match pure functions and actions haphazardly like that. Applying a function and executing an action are two different things, and will require different code.

Converting IO Int to Int

I've created a combobox from converting a xmlWidget to a comboBox with the function castTocomboBox and now I want to get the text or the index of the active item. The problem is that if I use the comboBoxGetActive function it returns an IO Int result and I need to know how can I obtain the Int value. I tried to read about monads so I could understand what one could do in a situation like this but I don't seem to understand. I appreciate all the help I can get. I should probably mention that I use Glade and gtk2hs.
As a general rule you write something like this:
do
x <- somethingThatReturnsIO
somethingElseThatReturnsIO $ pureFunction x
There is no way to get the "Int" out of an "IO Int", except to do something else in the IO Monad.
In monad terms, the above code desugars into
somethingThatReturnsIO >>= (\x -> somethingElseThatReturnsIO $ pureFunction x)
The ">>=" operator (pronounced "bind") does the magic of converting the "IO Int" into an "Int", but it refuses to give that Int straight to you. It will only pass that value into another function as an argument, and that function must return another value in "IO". Meditate on the type of bind for the IO monad for a few minutes, and you may be enlightened:
>>= :: IO a -> (a -> IO b) -> IO b
The first argument is your initial "IO Int" value that "comboBoxGetActive" is returning. The second is a function that takes the Int value and turns it into some other IO value. Thus you can process the Int, but the results of doing so never escape from the IO monad.
(Of course there is the infamous "unsafePerformIO", but at your level of knowledge you may be certain that if you use it then you are doing it wrong.)
(Actually the desugaring is rather more complicated to allow for failed pattern matches. But you can pretend what I wrote is true)
Well, there is unsafePerformIO: http://haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/System-IO-Unsafe.html#v:unsafePerformIO
(If you want to know how to find this method: Go to http://www.haskell.org/hoogle and search for the signature you need, here IO a -> a)
That said, you probably heard of "What happens in IO stays in IO". And there are very good reasons for this (just read the documentation of unsafePerformIO). So you very likely have a design problem, but in order to get help from experienced Haskellers (I'm certainly not), you need to describe your problem more detailed.
To understand what those types are –step by step–, first look up what Maybe and List are:
data Maybe a = Nothing | Just a
data [a] = [] | a : [a]
(Maybe a) is a different type than (a), like (Maybe Int) differs from (Int).
Example values of the type (Maybe Int) are
Just 5 and Nothing.
A List of (a)s can be written as ([ ] a) and as ([a]). Example values of ([Int]) are [1,7,42] and [ ].
Now, an (IO a) is a different thing than (a), too: It is an Input/Output-computation that calculates a value of type (a). In other words: it is a script or program, which has to be executed to generate a value of type (a).
An Example of (IO String) is getLine, which reads a line of text from standard-input.
Now, the type of comboBoxGetActive is:
comboBoxGetActive :: ComboBoxClass self => self -> IO Int
That means, that comboBoxGetActive is a function (->) that maps from any type that has an instance of the type-class ComboBoxClass (primitive type-classes are somehow similar to java-interfaces) to an (IO Int). Each time, this function (->) is evaluated with the same input value of this type (self) (whatever that type is), it results in the same value: It is always the same value of type (IO Int), that means that it is always the same script. But when you execute that same script at different times, it could produce different values of type (Int).
The main function of your program has the type (IO ()), that means that the compiler and the runtime system evaluate the equations that you program in this functional language to the value of main, which will be executed as soon as you start the program.

Resources