-1
  x = do
    first <- "mfwew"
    let q = first
    a <- q
    let b = a
    putStrLn (b)
    return b

how to use the assigned variable "first" to a <- q?

thank you

I want to do something like this

    do
      b <- func a
      c <- func1 b
      func2 c

but this won't work. I know its because the IO type doesn't match, but is there other way to do it? Specifically, i want to use b again in x <- xxx b.

user3230613
  • 133
  • 1
  • 5
  • 2
    I'm not sure what you want your code to do – your question isn't clear. Could you elaborate, maybe with the desired result? Relatedly, your code currently doesn't typecheck; you can't have `first <- "mfwew"` and `putStrLn (b)` in the same `do` block. – Antal Spector-Zabusky Feb 21 '16 at 07:12
  • This question cannot be answered without the types of `func`, `func1` and `func2` and the expected type of the whole `do` block. – Zeta Feb 21 '16 at 07:29
  • 1
    What do you mean "it won't work"? That works if, for instance, `func = return`, `func1 = return . reverse`, `func2 = putStrLn`, and `a = "Hello, world!"` – it prints `!dlrow ,olleH`. It sounds like you're having a typechecking issue, which means we need to see the specific code that doesn't typecheck in order to be helpful. – Antal Spector-Zabusky Feb 21 '16 at 07:30
  • check out [this answer](http://stackoverflow.com/questions/11323300/using-return-vs-not-using-return-in-the-list-monad/11326549#11326549) for some nice pictures and explanations. – Will Ness Feb 21 '16 at 10:05

2 Answers2

3

If I read your question and comments right than you want to just use the value of func a in func1 .. and you tried imperative do-style but then noticed that this only works for (the IO)-Monad(s).

In this case let comes quite close:

myResult a =
   let b = func a
       c = func1 b
   in func2 c

but in Haskell we usually do it with composition instead:

myResult a = func2 (func1 (func a))

which is

myResult a = func2 . func1 . func $ a

and finally you can drop the point a to get point-free-style:

myResult = func2 . func1 . func

if you like

Random Dev
  • 51,810
  • 9
  • 92
  • 119
2

The thumb rule is, you have to look at the type of your functions.

When a function returns IO (or any monad you are working in), use <- to run the monadic action, as in your code

do
  b <- func a
  c <- func1 b
  func2 c

When a function simply returns a value, without wrapping it in the monad, use let.

do  -- do is not really necessary here... but let's play along
  let b = func a
  let c = func1 b
  func2 c

Usually you need to mix both. E.g., if func is monadic while func2 is not, we write

do
  b <- func a
  let c = func1 b
  func2 c

Summing up: check the type of your functions.

chi
  • 111,837
  • 3
  • 133
  • 218