如何转换[(Data.Text.Internal.Text,Data.Text.Internal.Text)]->文本

时间:2019-07-05 12:31:55

标签: haskell haskell-stack

我制作了一个天气程序,其本质非常简单:用户输入该程序将使用的语言,城市和日期,然后我将其全部检查。但是,当用户输入正确的城市但带有小写字母时,尽管正确输入了城市

,程序仍会显示错误消息

我现在介绍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 

1 个答案:

答案 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