在哪里可以捕获异常?

时间:2018-10-23 15:22:44

标签: haskell time haskell-stack

我的代码:

{-# LANGUAGE MultiWayIf        #-}
{-# LANGUAGE OverloadedStrings #-}

module UserData where

import           Control.Exception
import           Data.Either
import           Data.Maybe
import           Data.Time         (getCurrentTime)
import           Data.Time.Clock
import           Data.Time.Format

import           Types

round' :: NominalDiffTime -> Integer
round' mark
    | mark < 0 = 0
    | mark2 > 100 = 100
    | otherwise = mark2
    where mark2 = round mark

supportedCities :: [City]
supportedCities = [Aragatsotn .. Yerevan]

getUserData :: IO (Either String (UTCTime,City))
getUserData = do
    date         <- getDateFromUser
    cityFromUser <- getCityFromUser
    if | isLeft date         -> return $ Left "error"
       | isNothing cityFromUser -> return $ Left "error"
       | otherwise      -> let [realDate] = rights [date] in return $ Right 

(realDate,仅来自cityFromUser)

getDateFromUser :: IO (Either String UTCTime)
getDateFromUser = do
  Prelude.putStrLn "Пожалуйста, укажите дату для прогноза в формате ГГГГ-ММ-ДД:"
  currentTime <- getCurrentTime
  date        <- Prelude.getLine
  let dayFromUser = parseTimeOrError True defaultTimeLocale "%Y-%m-%d %H:%M:%S" (date ++ " 12:00:00") :: UTCTime
  case dayFromUser of
    validDay -> do
          let differenceInNominalDiffTime = diffUTCTime validDay currentTime
              secondsInDay = 86400
              differenceInDays = round' $ differenceInNominalDiffTime / secondsInDay
          if differenceInDays >= 0 && differenceInDays <= 5
              then return $ Right validDay
              else return $ Left "asdasd"

getCityFromUser :: IO (Maybe City)
getCityFromUser = do
    Prelude.putStrLn "Пожалуйста, укажите один из этих марзов:"
    print [Aragatsotn .. Yerevan]
    cityFromUser <- Prelude.getLine
    let cityAsString = Prelude.map show supportedCities
    if cityFromUser `elem` cityAsString
       then return $ Just (read cityFromUser :: City)
       else return Nothing

此代码有效。

我遇到错误

但是据我了解解析函数,parseTimeOrError返回一个异常。我应该如何以及在何处捕获此异常?

也就是说,我需要显示一些字符串,而不是例外情况

例如“对不起,您的数据不正确”

1 个答案:

答案 0 :(得分:1)

对程序最简单的更改是使用parseTimeM而不是parseTimeOrError

Maybe是可以为m填充的可能类型之一,因此您可以编写:

parseTimeM True defaultTimeLocale "%Y-%m-%d %H:%M:%S" "2018-10-23 11:41:20" :: Maybe UTCTime

在您的程序中,validDay -> do可以更改为Just validDay -> do,GHC会推断Maybe,因此您不需要我在上面给出的显式类型签名。