Reputation: 39
I make a weather program whose essence is very simple: the user enters the language in which the program will work, the city and date, and then I check it all. But when the user enters the correct city but with a small letter, the program gives an error, although the city is entered correctly
I now about toLower
function, but i can't use it because of i get a pair of cities in type [(Text,Text)]
let pairsOfCityNames = [ let names = T.splitOn (",") twoNames
[nameForHuman, nameForServer] = L.filter (not . T.null) (names)
in (nameForHuman, nameForServer)
| twoNames <- cityNames
]
(allNamesForHumans, _) = unzip pairsOfCityNames
And i get something like:
[ ("Aragatsotn", "Aragatsotn")
, ("Ararat", "Ararat")
, ("Armavir", "Armavir")
, ("Dilijan", "Dilijan")
, ("Gegharkunik", "Gegharkunik")
, ("Gyumri", "Gyumri")
, ("Kotayk", "Kotayk")
, ("Shirak", "Shirak")
, ("Syunik", "Syunik")
, ("Vanadzor", "Vanadzor")
, ("Yerevan", "Yerevan")
]
I want when the user enters the correct city but with a small letter, the program works
And how i check it:
cityFromUser <- TIO.getLine
let lovercaseForCity = T.toLower cityFromUser
cityNameForServer <- case L.lookup lovercaseForCity pairsOfCityNames of
Nothing -> do
TIO.putStrLn $ messageErrorWrongCity phrasesForUser
exitFailure
Just cityNameForServer -> return cityNameForServer
TIO.putStrLn cityNameForServer
Upvotes: 0
Views: 89
Reputation: 16145
If I understand correctly, this list of pairs is meant to convert "ararat"
into "Ararat"
to compensate for the user's lack of Title Case, while the server you communicate with only accepts one capitalisation of a given city name.
But I could be wrong in this understanding.
You could use Data.Text.toTitle
:
do cityFromUser <- T.toTitle <$> TIO.getLine
...
Since you're dealing with input sanitation, you may also want to T.strip
leading and trailing whitespace from what the user entered. With T.toTitle
you could instead of a list of pairs use a Data.Set
of valid city names for the server:
import Data.Set (Set)
import qualified Data.Set as Set
type CityName = Text
validCityNames :: Set CityName
validCityNames = Set.fromList
[ "Aragatsotn"
, "Ararat"
, "Armavir"
, "Dilijan"
, "Gegharkunik"
, "Gyumri"
, "Kotayk"
, "Shirak"
, "Syunik"
, "Vanadzor"
, "Yerevan"
, ...
]
getValidCityNameFromUser :: IO (Maybe CityName)
getValidCityNameFromUser = do
cityNameFromUser <- T.toTitle . T.strip <$> TIO.getLine
if Set.member cityNameFromUser validCityNames
then return (Just cityNameFromUser)
else do
TIO.putStrLn $ messageErrorWrongCity phrasesForUser
exitFailure
Upvotes: 2