Как конвертировать [(Data.Text.Internal.Text, Data.Text.Internal.Text)] -> Текст - PullRequest
0 голосов
/ 05 июля 2019

Я создаю программу погоды, суть которой очень проста: пользователь вводит язык, на котором будет работать программа, город и дату, а затем я проверяю все это.Но когда пользователь вводит правильный город, но с маленькой буквой, программа выдает ошибку, хотя город введен правильно

Я теперь о 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 Ответ

2 голосов
/ 05 июля 2019

Если я правильно понимаю, этот список пар предназначен для преобразования "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
...