Skip to content

Instantly share code, notes, and snippets.

@denisshevchenko
Created April 6, 2018 16:11
Show Gist options
  • Save denisshevchenko/ad678f1badb68d346afbf4fde5b2cfa9 to your computer and use it in GitHub Desktop.
Save denisshevchenko/ad678f1badb68d346afbf4fde5b2cfa9 to your computer and use it in GitHub Desktop.
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE MultiWayIf #-}
module UserData where
import Text.Read (readMaybe)
import Data.Text
import qualified Data.List as List
import Data.Maybe (isJust, fromJust)
import qualified Data.Text.IO as TIO
-- Тип для всех городов, известных нашей программе.
data City
= Yerevan
| Aragacotn
| Ararat
| Armavir
| Gexarkunik
| Lori
| Kotayk
| Shirak
| Syunik
| Tavush
| Vanadzor
deriving Show
-- Тип для даты, в простейшем виде это просто строка,
-- в том её виде, в котором ввёл пользователь.
type Date = Text
-- Наша главная функция в этом модуле, она получает от пользователя
-- и дату, и город, проверяя, что всё в порядке. Если что-то введённое
-- некорректно - функция сообщит о проблеме.
getUserData :: IO (Date, City)
getUserData = do
date <- getDateFromUser
city <- getCityFromUser
return (date, city)
-- Здесь мы запрашиваем у пользователя дату и проверяем её корректность.
getDateFromUser :: IO Date
getDateFromUser = do
Prelude.putStrLn "Пожалуйста, укажите дату для прогноза в формате ДД/ММ/ГГГГ:"
date <- TIO.getLine
let dateParts = splitOn "/" date
if List.length dateParts == 3
then
let [day, month, year] = dateParts
datePartsAsNumbers = convertToNumbers day month year
numbersAreValid = checkNumbers datePartsAsNumbers
in if numbersAreValid
then return date
else return "" -- Здесь, на самом деле, нужно сообщить о проблеме.
else
return "" -- Здесь, на самом деле, нужно сообщить о проблеме.
where
convertToNumbers :: Text -> Text -> Text -> (Int, Int, Int)
convertToNumbers day month year =
let aDay = readMaybe (unpack day) :: Maybe Int
aMonth = readMaybe (unpack month) :: Maybe Int
aYear = readMaybe (unpack year) :: Maybe Int
isItDay = isJust aDay
isItMonth = isJust aMonth
isItYear = isJust aYear
in if isItDay && isItMonth && isItYear
then ( fromJust aDay
, fromJust aMonth
, fromJust aYear
)
else (0, 0, 0) -- Здесь, на самом деле, нужно сообщить о проблеме.
checkNumbers :: (Int, Int, Int) -> Bool
checkNumbers (day, month, year) =
let correctDay = day >= 1 && day <= 31
correctMonth = month >= 1 && month <= 12
correctYear = year >= 2018
in correctDay && correctMonth && correctYear
-- Здесь мы запрашиваем у пользователя марз и проверяем, что он входит в список наших марзов.
getCityFromUser :: IO City
getCityFromUser = do
Prelude.putStrLn "Пожалуйста, укажите марз в Армении, на английском языке:"
city <- Prelude.getLine
if | city == show Yerevan -> return Yerevan
| city == show Aragacotn -> return Aragacotn
| city == show Ararat -> return Ararat
| city == show Armavir -> return Armavir
| city == show Gexarkunik -> return Gexarkunik
| city == show Lori -> return Lori
| city == show Kotayk -> return Kotayk
| city == show Shirak -> return Shirak
| city == show Syunik -> return Syunik
| city == show Tavush -> return Tavush
| city == show Vanadzor -> return Vanadzor
| otherwise -> return Yerevan -- Здесь, на самом деле, нужно сообщить о проблеме.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment