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
a source to share
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]
a source to share
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"
a source to share
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.
a source to share
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.
a source to share