[Haskell-beginners] Re: the role of assignments

Ertugrul Soeylemez es at ertes.de
Thu Jul 1 21:27:00 EDT 2010


prad <prad at towardsfreedom.com> wrote:

> i'm trying to sort the assignment concept out in my mind.  as i
> understand it so far,
>
> <- is for IO
> so you can do something like
> someIOVar <- readFile filename
> this will be of type IO String
>
> which is different from String as in
>
> let someStrVar = "this is a string"
>
> to work with an IO String you need to convert it into a String which
> seems to automatically happen inside a do structure as in:
>
> main = do
>     tmplX <- readFile "zztmpl.htm"
>     navbx <- readFile "zznavb.htm"
>     let page = U.replace tmplX "NAVX" navbx
>
> are there some other ways to make IO String into String?

I think, you're building up the wrong intuition here.  Let me try to
correct it.  First of all that neat left-arrow belongs to the 'do'
notation.  On the right hand side of the arrow you place an IO
computation.  On the left hand side you put a name for its result.  This
is not an assignment.  You just give the result of the computation a
name.  If the computation is of type 'IO a', then that result is of type
'a'.  Example:

  do line <- getLine
     putStr "You entered: "
     putStrLn line

getLine is a computation of type IO String, so 'line' is of type String.
There is no conversion involved, because actually there is no "running"
involved at all.  You just describe what happens, /when/ the 'main'
computation is run.  As you can see from its type, it's also an IO
computation:

  main :: IO ()

Note that others have already noted that the 'do' notation as well as
the '<-' operator, which belongs to it, is more general than that.  This
is true, but you can safely ignore that for now, until you have
understood the general concept.


> also, it seems that assignment is different for the '=' in a program
> vs ghci for functions:
>
> sum x y = x + y (program)
> vs
> let sum x y = x + y (ghci)
>
> but not for strings and other things because you must always preface
> assignment of values with 'let':
>
> let a = 4
>
> i suppose the let is there for variable assignments because such
> things necessitate a change of state and i've read that this is not
> desirable in functional programming - you have to work a little harder
> to do assignment than languages which just allow
> a = 4
> b = 5
> c = 6
> etc
>
> in haskell, is it preferable to do something like this:
>
> var <- readFile fn
> someFunction var
>
> or someFunction (readFile fn)

In its raw form there are no mutable variables in Haskell.  Technically
there are, but from a high level language perspective there is no
mutation.  Whenever an equals sign is involved, this is just name
giving, not an 'assignment' in the usual sense.  Example:

  sum x y = x + y

This gives 'x + y' a name, namely 'sum x y'.  This really is an
equation, so whenever you write 'x + y', you can safely replace it by
'sum x y' and vice versa.  The same holds for 'let' and 'where', but
unlike a top level definition they are scoped.  You can view GHCi's
command line as one 'do' block, which gets executed as you type it.
That's why you need 'let'.  You can't write top level definitions in
GHCi.

And the difference between '<-' and '=' is that '<-' gives the result of
an IO computation a name, so you can refer to it.  '=' just gives a
value a name, where a value can be a function, too.  In a 'let'
construct, both sides of the equation have the same type.  In a '<-'
construct the right side has type 'IO a' and the left side has type 'a'.

  Right: let a = 4
  Right: x <- getLine
         print (read x + 1)

Now a few wrong ones with explanations:

  Wrong: putStrLn getLine

Reason:  putStrLn has the type 'String -> IO ()', so it expects a
String, but getLine is of type 'IO String', not 'String'.

  Wrong: let x = getLine

This doesn't produce an error by itself, but remember that both sides of
an equation must have the same type.  So x is of type 'IO String' now.

  Wrong: y <- x^2

The right hand side of '<-' must be of type 'IO a', but 'x^2' is of type
(say) 'Integer'.  This doesn't fit.

I hope, this helps.


Greets,
Ertugrul


-- 
nightmare = unsafePerformIO (getWrongWife >>= sex)
http://blog.ertes.de/




More information about the Beginners mailing list