How does the Haskell compiler "know" that IO cannot be unwrapped? - haskell

Obviously, the following function is impossible, because it is impossible to unwrap an IO value permanently (ignoring unsafePerformIO or similar):
unwrapIO :: IO String -> String
unwrapIO (IO str) = str
However, similar functions such as the following are possible:
unwrapJust :: Maybe String -> String
unwrapJust (Just str) = str
unwrapJust Nothing = "ignore this plz"
I fully understand the reasoning behind why #2 is possible but #1 is not, but I do not understand how. Can I also make my own types that are not unwrappable?

Just and Nothing are data constructors for the type Maybe a. IO has no data constructors to speak of (in GHC it actually has constructors but they're really implementation details of GHC, and other implementations might define IO differently).
unwrapIO (IO str) = str doesn't make sense in the same way unwrapMaybe (Maybe str) = str doesn't make sense. IO and Maybe are not data constructors, so you cannot pattern-match on them.

It's because the data constructor of IO is not exported. I mean, you can think it's not exported.
You can prevent your own type from being unwrapped by using the same strategy.
module Test (Test, test) where
data Test a = MkTest a
test :: a -> Test a
test = MkTest
You can create a value of Test using test, but you cannot unwrap it using pattern-match because MkTest is not exported.

I believe that while the existing answers are mostly true, there is a deeper reason why IO can not be unwrapped. Conceptually, type IO a = RealWorld -> (a, RealWorld). IO is a function type (in real implementations hidden behind a newtype wrapper or equivalent machinery).
So, how would you go about unwrapping a function? Easy, you just call it!. But how are you going to get an instance of RealWorld? That is the truer primitive: you can not construct a RealWorld, there is only ever one.
The monadic instance of course can just pass RealWorld as a state, kind of like StateT and in the end, the only instance ever constructed is at startup of the program, then it is passed down between the IOs.
Coming back to reality again, this is (again) a lie. You actually can get hold of an instance of RealWorld and you can call an IO a action "ahead of time". There is a function that does exactly what you asked for. It is called System.IO.Unsafe.unsafePerformIO :: IO a -> a though it is in an unsafe package for a reason.

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

Opposite of Maybe data type

So the Maybe data type is defined like this:
data Maybe a = Just a | Nothing
What would you call the data type that's conceptually opposite to Maybe:
data <Type> = Okay | Error String
That is, a type that declares the computation successful or holds some error produced by the computation.
I refute the premise that this type is in a meaningful sense “opposite” to Maybe. I also don't agree that Either should generally be understood as an error-signalling type – that's just quite a natural way of using it, due to the way its monad instance works.
Both Maybe and Either know nothing about errors / failure – they're just implementations of the abstract concept of a sum type (in the case of Maybe a sum with the unit type).
IMO, you should just use Maybe String for this purpose, or if you like it explicit:
type ErrorMsg = String
type PossibleError = Maybe ErrorMsg
I would use Either String (), using the common convention that an Either is used to signal errors with information in the Left and the success value in the Right. If you don't actually have a success value, use the unit type ().
Of course, that still needs to be wrapped in some monad, because in Haskell a pure function without a result is not useful. If the purpose of your function is just to check the validity of some data, then it's not an error to return the error string, and I'd go back to using Maybe.
Your <Type> is equivalent to Either String (), so you could just have
type CanError = Either String ()
isOkay :: CanError -> Bool
isOkay = Data.Either.isRight
isError :: CanError -> Bool
isError = Data.Either.isLeft
getErrorMsg :: CanError -> Maybe String
getErrorMsg (Left msg) = Just msg
getErrorMsg _ = Nothing
You can use Either String as a Monad/Applicative/Functor, but not CanError since it has kind *, not * -> * as required by each of those typeclasses. I would recommend just using Either String as is since you get the extra power of Monad/Applicative/Functor/etc., and when you need the equivalent of CanError just have the return type be Either String () in-line.
Another example for what perhaps is the general idea behind your question, that success is the exceptional case and failure is the normal case, is EitherR as provided in the errors package whose Monad instance is suggestively referred to as the "success" monad. As the name suggests there's no magic here, it's just a newtype with Monad instances swapped around. The interpretation, however, is interesting.
You can program in a world where success falls through while errors are kept around. As the package documentation indicates, this comes in handy when dealing with stacks of exception handlers.

Is there a useful inhabitant for the type `forall v. Int -> v -> IO v`?

Let's say we want to write a generic property map backed by IO operations,
but for some reason we are required to make the value type polymorphic.
type Key = Int
get:: Key -> v -> IO v -- Takes a key and a default value, return the associated value
put:: Key -> v -> IO () -- store (Key,v) pair doing some IO
Do Free Theorems require that get and put do only trivial things in this case too,
and if so, can we cheat the ghc's type system to implement a real type-indexed
IO database?
Generally, strange things may happen in IO, so I do not think that there is a rigorous notion of Free Theorems involving IO. Anyways, from what I know about IO as it is implemented, assuming the functions do
nothing that can crash (such as doing pointless pointer arithmetic to produce a value of type v),
not use any of the unsafe functions (which generally break any Free Theorems-like reasoning),
do not return bottom (e.g. undefined or an exception) and
do eventually “return”
then the “returned” value will be the parameter.
But this means that it is not possible to implement a type-indexed database using IO.
It would be possible with a Typeable a constraint. In that case, the expected Free Theorem does not hold and a get function would be allowed to return something else than the default value.

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