We can imagine that you are asking for a name to print it out and then rewrite it.
In pseudo code, we have
main = print "what is your name" bind varname with userReponse print varname
Then your question is about the second instruction.
Take a look at the semantics of this.
- userReponse is a function that returns user input (getLine)
- varname is var
- binding var with fun: this is a function that binds var (varname) to the output of the function (getLine)
Or, as you know, in haskell all this is a function, then our semantics are not very suitable.
We need to revise it to respect this idiom. According to a later reflection, the semantics of our binding become binding fun to fun
Since we cannot have a variable, pass an argument to a function, we need, at first glance, to call another function to produce them. So we need a way to connect the two functions, and that is what bind should do. In addition, as follows from our example, the evaluation order should be followed, and this will lead us to the next rewrite with fun bind fun
This means that the binding is more than the function that it performs. Then for all functions f and g we have f bind g.
In haskell, we mark this as follows
f >>= g
Also, since we know that a function takes 0, 1 or more arguments and returns 0, 1 or more arguments.
We could clarify our definition of our bind statement.
In fact, when f returns no result, mark β = as β
By applying, theses of reflexes to our pseudo-code lead us to
main = print "what your name" >> getLine >>= print
Wait a minute. How does a snap operator differ from using a point operator for a composition of two functions?
It is very different because we omit important information; binding does not connect two functions, but a whole chain of calculations . And the thing is to understand why we defined this operator.
Record the global calculation as a unit sequence.
f0 >>= f1 >> f2 >> f3 ... >>= fn
At this stage, global computation can be defined as a set of computations with two operators β = , β .
How do we present a set in computer science?
Usually a container .
Then global computing is a container which contains several units of calculation . On this container, we could define some operator that allows us to move from the unit of calculation to the next, taking into account or not the result later, this is our β = and β .
As a container, we need a way to insert a value, this is done using the return function. Which take the object and enter it into the calculation , you can check it through the signature.
return :: a -> ma -- m symbolize the container, then the global computation
Like this calculation , we need a way to manage the failure, which is performed by the fail function.
Actually the calculation interface is defined by the class
class Computation return
Now we can refine our code by following
main :: IO () main = return "What your name" >>= print >> getLine >>= print
Here, I intentionally include the signature of the main function to express the fact that we are in the global IO calculation, and the result is with () (as an exercise, enter $: t print in ghci).
If we pay more attention to the definition for β = , we can derive the following syntax
f >>= g <=> f >>= (\x -> g) and f >> g <=> f >>= (\_ -> g)
And then write
main :: IO () main = return "what your name" >>= \x -> print x >>= \_ -> getLine >>= \x -> print x
As you should suspect, we certainly have special syntax for working with the bind operator in a computing environment. You are right, this is the purpose of the do syntax
Then our previous code will become, with do syntax
main :: IO () main = do x <- return "what your name" _ <- print xx <- getLine print x
If you want to know more, see monad
As mentioned earlier, my initial conclusion was a bit enthusiastic
You should be shocked because we have a gap of referential transparency (x takes two different values ββinside our sequence of commands), but it doesnβt matter anymore, because we are in the calculation , and the calculation , as defined below, is the container from which we can get an interface, and this interface is designed to control, as you can explain, the unclean world, which corresponds to the real world.