haskell - 字符串到术语,如果不存在术语 - 捕获错误
问题描述
处理任务,针对不同情况实施错误消息。如果没有定义的术语,则将字符串转换为术语时会卡住。
这是我的程序:
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"
or 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
成功的情况。
推荐阅读
- javascript - 使用 FS 读取字符串会返回此错误:位置 0 处 JSON 中的意外标记 r
- azure - 如何使用 Azure 云函数从 CosmosDB 中删除文档?
- java - 将对象转换为字节的设计模式
- android - Xamarin.Android 应用的静音
- python - 为什么在无服务器 Python 应用程序中使用 zappa/chalice?
- powershell - Vagrant 和 Virtual Box 都安装了我的 vagrant up 命令给出路径错误
- javascript - 自定义js选择下拉选项不变
- excel-dna - ExcelDna xll 插件未显示,但功能可见,为什么?
- python - Python 附加到 .txt
- r - 将列的相似值组合成行