
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/