字符串到术语,如果不存在术语 - 捕获错误

问题描述

正在处理任务,针对不同情况实施错误消息。如果没有定义的术语,则在将字符串转换为术语时会卡住。

这是我的程序:

readPhone :: String->String->String->Phone
readPhone typee countrycode phoneno
    |head(countrycode)=='+'=error "+ found"
    |typee==""=error "Missing phone type"
    |otherwise=makePhone (stringToTerm typee) (toCountryCode(read countrycode)) (toPhoneNo(read phoneno))

stringToTerm :: String  -> PhoneType
stringToTerm stringEvent = read $ stringEvent ++ " " 

scanStringCC :: String -> CountryCode
scanStringCC x = if all (`elem` "0123456789") x
                 then read x :: CountryCode
                 else 0





data PhoneType = WorkLandline|PrivateMobile|WorkMobile|Other deriving (Read,Show,Eq)

newtype PlainString = PlainString String
instance Show PlainString where
  show (PlainString s) = s
--instance Num Int where
--   (*)=int_times
--   (+)=int_plus

data CountryCode = CountryCode
    {
        cCode :: Integer
    } deriving (Eq,Read)

instance Show CountryCode where
    show (CountryCode a)=(show (PlainString "+")) ++ (show a)
instance Num CountryCode where 
    CountryCode a * CountryCode b = CountryCode (a * b)
    CountryCode a + CountryCode b = CountryCode (a + b)
    CountryCode a - CountryCode b = CountryCode (a - b)
    fromInteger x = CountryCode (fromInteger x)

toCountryCode :: Integer->CountryCode
toCountryCode ccode  
    | ccode<0=error "Negative country code"
    |otherwise = CountryCode ccode


data PhoneNo = PhoneNo
    {
        pNo :: Integer
    } deriving (Read,Eq)
instance Show PhoneNo where
    show (PhoneNo a)=show a
instance Num PhoneNo where
    PhoneNo a + PhoneNo b=PhoneNo(a+b)
    PhoneNo a - PhoneNo b=PhoneNo(a-b)
    PhoneNo a * PhoneNo b=PhoneNo(a*b)
    fromInteger x = PhoneNo (fromInteger x)

toPhoneNo :: Integer -> PhoneNo
toPhoneNo pno  
    | pno<0=error "Negative phone number"
    |otherwise = PhoneNo pno

data Phone = Phone
    {
        phoneType :: PhoneType,countryCode :: CountryCode,phoneNo :: PhoneNo
    } deriving (Read,Eq)
instance Show Phone where
    show (Phone a b c)=show b ++ (show (PlainString " ")) ++ show c ++(show (PlainString "(")) ++ show a ++ (show (PlainString ")"))

makePhone :: PhoneType -> CountryCode  -> PhoneNo -> Phone
makePhone phonetype countrycode phoneno
    |otherwise = Phone phonetype countrycode phoneno

适用于 readPhone "Other" "358" "2"readPhone "" "358" "2"(最后一个给出了“缺少电话类型”错误,这是正确的

但是,如果我给出 readPhone "notexist "358" "2",它会显示 +358 2(--- Exception: Prelude.read: no parse

如何捕捉它以显示正确的错误代码“电话类型不正确”

解决方法

您的 stringToTerm 函数使用 read 函数来解析 PhoneType,当它无法解析类型时,这将失败并出现错误。 如果您想自己处理这种情况,您应该使用 readMaybe 并处理返回的 Maybe :

stringToTerm :: String -> PhoneType
stringToTerm stringEvent = case readMaybe stringEvent of 
  Just phoneType -> phoneType 
  Nothing -> error "Incorrect phone type"

使用错误来表示验证失败不是很惯用的 Haskell,我认为更好的方法是将 readPhone 函数的签名更改为

readPhone :: String -> String -> String -> Either String Phone

并在验证失败时返回 Left "error message",在成功时返回 Right phone

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...