如何转换 [(Data.Text.Internal.Text,Data.Text.Internal.Text)] -> 文本
How to convert [(Data.Text.Internal.Text,Data.Text.Internal.Text)] -> Text
我制作了一个天气程序,其本质非常简单:用户输入程序运行的语言、城市和日期,然后我检查所有内容。但是当用户输入正确的城市但带有小写字母时,程序报错,虽然城市输入正确
我现在正在使用 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
如果我没理解错的话,这个配对列表是为了将 "ararat"
转换成 "Ararat"
以弥补用户缺少 Title Case,而您与之通信的服务器只接受一个大写给定的城市名称。
但我的理解可能是错误的。
您可以使用 Data.Text.toTitle
:
do cityFromUser <- T.toTitle <$> TIO.getLine
...
由于您要处理输入卫生问题,您可能还需要 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
服务器的有效城市名称:
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
我制作了一个天气程序,其本质非常简单:用户输入程序运行的语言、城市和日期,然后我检查所有内容。但是当用户输入正确的城市但带有小写字母时,程序报错,虽然城市输入正确
我现在正在使用 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
如果我没理解错的话,这个配对列表是为了将 "ararat"
转换成 "Ararat"
以弥补用户缺少 Title Case,而您与之通信的服务器只接受一个大写给定的城市名称。
但我的理解可能是错误的。
您可以使用 Data.Text.toTitle
:
do cityFromUser <- T.toTitle <$> TIO.getLine
...
由于您要处理输入卫生问题,您可能还需要 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
服务器的有效城市名称:
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