Nested if in haskell

// change 5 when I only use these 2 lines

  index :: [String] -> [String] -> Bool
  index a b = and [x `elem` a |x <- b]

      

it works great !!!!

eg:

index ["asd", "asdd", "dew"] ["asdd", "asdad"]

False

But when i use all the code mentioned below

empty [] = True
empty _ = False

    index a b = do
             if empty a
              then do putStrLn "a is empty"
                      else return ()
             if empty b
              then do putStrLn "b is empty"
                      else return ()
        where
          index :: [String] -> [String] -> Bool
          index a b = and [x `elem` a |x <- b]

      

theres no way out !! and that's the problem i got !!

// edit 6

index a b = do index'
         if empty a
          then do putStrLn "a is empty"
                  else return ()
         if empty b
          then do putStrLn "b is empty"
                  else return ()
    where
      index' :: [String] -> [String] -> Bool
      index' a b = and [x `elem` a |x <- b]

      

thanks

+1


a source to share


4 answers


This is a bit off-topic because you might be trying to learn the layout rule and how to nest ifs, but the code you show in revision 6 just uses it if

to check for errors. I would just do error checking with pattern matching instead if

.

index [] _ = putStrLn "a is empty"
index _ [] = putStrLn "b is empty"
index a b = putStrLn (show index')
    where index' = and [x `elem` a | x <- b]

      

(You don't need return ()

after putStrLn

, because it already returns ()

for you.)

Pattern matching is much easier because it doesn't require a lot of indentation, etc.




Edit:

I have changed the definition index'

slightly from yours. In my version, this is a local variable instead of a local function. In Haskell, there is not much difference, just index'

uses a

and b

from the environment index

, so it does not need to take parameters. (Admittedly index'

not such a good name for a variable.)

Also I settled on type annotations because I don't usually write them. But they are useful when things don't work. This is how it looks:

    where index' :: Bool
          index' = and [x `elem` a | x <- b]

      

+4


a source


A construct if

in Haskell is an expression. This means it should always evaluate the value, so the part else

is required.

Also, the first part has if

to be boolean, so you cannot call index'

there, as it returns [Int]

, not Bool

.



I would say start with something like this:

if isEmpty a
then putStrLn "a is empty"
else if isEmpty b
     then putStrLn "b is empty"
     else putStrLn "neither are empty"

      

+2


a source


I / O operations in Haskell are a bit tricky because they need so called monads. You need the special do

-notion here for the sequence of outputs.

Write it like this:

empty [] = True
empty _ = False

index a b = do
         if empty a
          then do putStrLn "a is empty"
          else return ()
         if empty b
          then do putStrLn "b is empty"
          else return ()

      

Or maybe you can just return strings and use them putStrLn

separately. You index'

must return a boolean when it is to be used as an if condition.

0


a source


index a b = if index' [] bs
                       then putStrLn "a is empty"
                       if index' a []          
                        then putStrLn "b is empty"
                        else                  
    where 
        index' :: [String] -> [String] -> [Int]
        index' a b = index' True [(elem x b) | x <- a]

      

If you do the way you do, you will see that the first one if does not have a corresponding else clause.

Also, the else clause does not return anything - the function must have a return value under all circumstances.

0


a source







All Articles