1

So I am just getting the hang of Haskell and got stuck with the syntax for creating nested if-else statements with Do. I am not sure, if I am supposed to use multiple Do's or if I can accomplish it all with just one. I am also not sure if I should use the return statement and if all the semicolons are necessary.

I tried adding and removing braces, return statements, semicolons, different indenting and do not know what else to try.

I get errors like " • Couldn't match expected type ‘m0 (m0 b0)’ with actual type ‘Int’ • In a stmt of a 'do' block: a <- getVal "

  1. This is the kind of structure I am trying to build but it gives me errors. You can imagine the getVal functions as arbitrary functions, that return an integer :

    func :: Int -> Int
    func val = do {
       if val < 10
          then do {
              a <- getVal0;
              b <- getVal1;
              if (val+a+b) < 0
                 then return 1
                 else return 2}
          else if val > 10 
              then do {
                 a <- getVal2;
                 b <- getVal3;
                 if (val + a +b) < 0 
                   then return 0
                   else return 1}
          else return 99;     }
    

An example of get val would be:

    getVal :: Int
    getVal  = 5

So this is what I want to happen :

If val is < 10, then get the value a with 2 parameters from getVal0 and get b from getVal1 . Then add val+a+b and if that is smaller than 0, return 1, else 2

If val is > 10, then get a from getVal2 and get b from getVal3. If val+a+b <0 then return 0, otherwise 1 .

If val is neither <10 or >10 ( val = 10) then return 99

Thanks for feedback and help!

10
  • 2
    what are getVal0 and getVal1? But it looks like you are trying to use a do block where it is both unnecessary and invalid. do blocks are only for computations within a monad - Int is not a monadic value so you can't use a do block to calculate such a value. Commented Feb 9, 2019 at 17:12
  • 8
    do doesn't do what you think it does. Ditto return and <-. This function needs none of those. Commented Feb 9, 2019 at 17:14
  • 3
    Perhaps you want to use the let ... in ... syntax here. Commented Feb 9, 2019 at 17:18
  • 2
    I tried writing an answer but this is too broad; requires explaining haskell syntax, purity, do notation, etc, etc. Even trying to fix this code block depends very much on the type of the made-up getVal1. Could you try asking just a single question, with an MCVE if you are still stuck? Commented Feb 9, 2019 at 17:36
  • 2
    @jberryman I think an answer that simply shows the correct way to use let, without getting into why do is inappropriate, would be sufficient. The OP commented that getVal0 and getVal1 are functions, so we can assume that something like let a = getVal0 parm1 parm2 in ... is the intent. Commented Feb 9, 2019 at 17:49

1 Answer 1

5

As already mentioned in the comments, you don't need do, <-, or return here. Those are for monadic code, but here you are defining a regular function -- there are no monads around.

So, we can instead use let .. in ... Here's a possible way, performing minor changes to the original code.

func :: Int -> Int
func val =
   if val < 10 then let
      a = getVal0
      b = getVal1
      in if val + a + b < 0
         then 1
         else 2
   else if val > 10 then let
      a = getVal2
      b = getVal3
      in if val + a + b < 0 
         then 0
         else 1
   else 99

Many Haskellers would consider to turn the outermost ifs into guards:

func :: Int -> Int
func val
   | val < 10 = let
      a = getVal0
      b = getVal1
      in if val + a + b < 0
         then 1
         else 2
   | val > 10 = let
      a = getVal2
      b = getVal3
      in if val + a + b < 0 
         then 0
         else 1
   | otherwise = 99
Sign up to request clarification or add additional context in comments.

1 Comment

Totally helped me implement the problem I was stuck with, thanks a lot!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.