
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? 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 friendship, prad ... with you on your journey Towards Freedom http://www.towardsfreedom.com (website) Information, Inspiration, Imagination - truly a site for soaring I's

<- isn't just for IO; it's part of "do" notation's syntactic sugar. It
is actually (in your first example) passing the unwrapped result
(String; not IO String) of ``readFile filename" to an anonymous
function.
I'd recommend reading ch. 14 of Real World Haskell (
http://book.realworldhaskell.org/read/monads.html )
On 7/1/10, prad
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?
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 friendship, prad
... with you on your journey Towards Freedom http://www.towardsfreedom.com (website) Information, Inspiration, Imagination - truly a site for soaring I's _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

On 2 July 2010 01:59, prad
i'm trying to sort the assignment concept out in my mind. as i understand it so far,
<- is for IO
Not really :) <- is for working with monads. It is just syntactic sugar that makes using monads a bit more pleasant
so you can do something like someIOVar <- readFile filename this will be of type IO String
which is different from String as in
Yes, because underneath what is really going on is the compiler is changing that to readFile fileName >>= \x -> ... 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?
Not that you should be using before leaning how monads work ;) But there is unsafePerformIO
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)
in ghci you are *inside* the IO monad. Hence the need for let bindings
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)
actually this won't work, unless somefunction has type IO String -> IO a. You would need somefunction =<< readFile fn and that would have type IO a assuming somefunction returns something of type a
-- In friendship, prad
... with you on your journey Towards Freedom http://www.towardsfreedom.com (website) Information, Inspiration, Imagination - truly a site for soaring I's _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
You definitely need to read up on monads and the do notation. All will become clearer :) Ben

On Friday 02 July 2010 02:12:23, Benjamin Edwards wrote:
But there is unsafePerformIO
Which is *really* unsafe and should only be used when one knows that here, in this place it is okay to use. There are places where unsafePerformIO is safe or needed (even if not entirely safe), but those are rare.

prad
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/

I think, you're building up the wrong intuition here. Let me try to correct it.
On Fri, 2 Jul 2010 03:27:00 +0200
Ertugrul Soeylemez
This is not an assignment. You just give the result of the computation a name.
this is very meaningful to me. thinking about it as you say really makes a difference in clarity for me.
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.
ya this too is something to understand - my reasoning has been pythonish and that is likely a big part of the problem.
As you can see from its type, it's also an IO computation:
main :: IO ()
this came as big surprise - but of course, now i think "what else could it possibly be?"
Whenever an equals sign is involved, this is just name giving, not an 'assignment' in the usual sense.
again this requires a conceptual shift for me.
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.
that clears up a big mystery. one of the tutorials i read pointed out that things are just done 'differently' in ghci, but didn't explain the rationale as you have done.
I hope, this helps.
it most certainly has!!! thanks to you and the other write-ups here, i'm starting to see haskell differently which will no doubt result in constructing programs successfully. despite the difficulties i'm having, i've been convinced this is all worth learning. and without doubt, the tone and activity of this board and its people have much to do with it! -- In friendship, prad ... with you on your journey Towards Freedom http://www.towardsfreedom.com (website) Information, Inspiration, Imagination - truly a site for soaring I's

He Prad, do line <- getLine putStr "You entered: " putStrLn line The example of Ertugrul is desugared to the following: getLine >>= \x -> putStr "You entered: " >> putStrLn x or even: getLine >>= \x -> putStr "You entered: " >>= (\_ -> putStrLn x) It helps a lot to not use the sugared syntax, until you know how to write them without the sugar. That way you will grasp the concept of monads much faster. it is also a matter of taste, for small monadic functions I prefer the desugared style. For longer it becomes a bit unwieldy. Greetings, Edgar

As an aside I think when I was first starting out on the path to understanding what the hell was going on with monads, I found the following blog post was very insightful: http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html Regards, Ben
participants (6)
-
Benjamin Edwards
-
Daniel Fischer
-
edgar klerks
-
Ertugrul Soeylemez
-
Jordan Cooper
-
prad