我制作了一个天气程序,其本质非常简单:用户输入该程序将使用的语言,城市和日期,然后我将其全部检查。但是,当用户输入正确的城市但带有小写字母时,尽管正确输入了城市
,程序仍会显示错误消息我现在介绍toLower
函数,但是因为有一对类型为[(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
我得到类似的东西:
[ ("Aragatsotn", "Aragatsotn")
, ("Ararat", "Ararat")
, ("Armavir", "Armavir")
, ("Dilijan", "Dilijan")
, ("Gegharkunik", "Gegharkunik")
, ("Gyumri", "Gyumri")
, ("Kotayk", "Kotayk")
, ("Shirak", "Shirak")
, ("Syunik", "Syunik")
, ("Vanadzor", "Vanadzor")
, ("Yerevan", "Yerevan")
]
我希望当用户输入正确的城市但带有一个小写字母时,程序运行正常
我如何检查它:
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
答案 0 :(得分:2)
如果我理解正确,那么此对列表旨在将"ararat"
转换为"Ararat"
,以补偿用户缺少标题的情况,而您与之通信的服务器仅接受给定字母的大写城市名称。
但是在这种理解上我可能是错的。
您可以使用Data.Text.toTitle
:
do cityFromUser <- T.toTitle <$> TIO.getLine
...
由于您要处理输入卫生,因此您可能还想从用户输入的内容开始T.strip
开头和结尾的空格。使用T.toTitle
,您可以使用Data.Set
代替服务器的有效城市名称来代替配对列表:
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