Search code examples
haskell

function that validates an address in Haskell


I made 3 functions which work perfectly fine each alone:

  • checkNumber -checks if a string contains only digits
  • checkStreetName - checks if a string contains only letters
  • isAbbreviation - checks if a string is "Ave." or "St."

I made the function checkAdd that uses the other functions

the function checkAdd gets a list of strings and should return True if:

the first string contains only numbers

the last string ="Ave." or St."

and the rest of the strings in between should contain letters

for example: ["123", "asdd", "Ave."] is legal address

However I am getting false instead of true and I don't know why. I checked each and every function alone. (by the way I am not allowed to use some of the ready made functions in Haskell)

so for this input : ["123", "asdd", "Ave."] I got false . why?

I must also say that the strange thing is that it works fine when I keep 2 conditions instead of 3 in checkAdd

checkNumber:: String->Bool
checkNumber  xs =((length(filter isDigit xs ))== length(xs))

checkStreetName:: String->Bool
checkStreetName xs  =((length(filter isLetter1 xs ))== length(xs))

isLetter1:: Char->Bool
isLetter1 ch   =((ch>='A' && ch<='Z') || (ch>='a' && ch<='z'))


checkAdd :: [String]->Bool
checkAdd (num:xs) = (checkNumber num  &&  (all1 checkStreetName (tail xs)) &&        isAbbreviation (last1 xs))


all1 :: (String->Bool)->[String] -> Bool
all1 f xs = ((length(filter f xs)) == length(xs))

isAbbreviation:: String->Bool
isAbbreviation str |str=="Ave." || str=="St."    =True
               |otherwise                    =False

last1 :: [a]->a
last1 (x:[])      = x
last1 (x:xs)      =last1 xs

Solution

  • The problem you have is simply that "Ave." contains a non-letter character, namely '.', but all1 (just a re-definition of all) requires it to fulfill checkStreetName. To fix this, for instance test all1 checkStreetName $ init xs instead of all1 checkStreetName xs.