我有一个程序,这是专门创建“学生”(名字,姓氏,年龄)和验证输入数据。我的问题是:当我插入学生时,例如名字不是2个字母或者年龄小于18岁-程序只显示一个错误。如何使用“任一函数”创建一个包含所有错误的字符串?
module Student where
data Student = Student {firstName::FirstName, lastName::LastName, age::Age}
deriving Show
newtype FirstName = FirstName String
deriving Show
newtype LastName = LastName String
deriving Show
newtype Age = Age Int
deriving Show
mkStudent :: String -> String -> String -> Either String Student
mkStudent fn ln a =
Student <$> validate fn
<*> validate ln
<*> validate a
aceptableLetters = ['a'..'z']++['A'..'Z']
validateFn :: String -> Either String FirstName
validateFn fn
| length fn < 2 = Left "First name has to at least 2 letters"
| length fn > 100 = Left "First name is limited to 100 characters"
| not . null $ filter (\c -> not . elem c $ aceptableLetters) fn = Left "First name contains unacceptable chars"
| otherwise = Right . FirstName $ fn
validateLn :: String -> Either String LastName
validateLn lastName
| length lastName < 2 = Left "Last name has to at least 2 letters"
| length lastName > 100 = Left "Last name is limited to 100 characters"
| not . null $ filter (\c -> not . elem c $ aceptableLetters) lastName = Left "Last name contains unacceptable chars"
| otherwise = Right . LastName $ lastName
validateA :: String -> Either String Age
validateA a
| age <= 18 = Left "Student has to be at least 18"
| age > 100 = Left "Student has more than 100 years. Probably it is an error."
| otherwise = Right . Age $ age
where
age = read a
class Validate v where
validate :: String -> Either String v
instance Validate FirstName where
validate=validateFn
instance Validate LastName where
validate=validateLn
instance Validate Age where
validate=validateA
发布于 2019-05-29 23:18:27
一种简单的解决方法是将左侧的Either
更改为自定义数据类型。我的意思是,您可以使用Either ErrorType Age
代替Either String Age
,然后定义
data ErrorType = LowAge | WrongName
在我看来,这也是更好的编程实践,因为您可以将错误抛出和它的处理程序分开。特别是在Haskell和函数式编程中,我不会随身携带字符串表示来处理错误。然后,例如,您可以将错误组合到一个列表中,即:
mkStudent :: String -> String -> String -> Either [ErrorType] Student
然后,只需使用另一个函数来处理列表并将其打印给用户,或记录该列表,或执行您想要对其执行的任何操作。
https://stackoverflow.com/questions/56363625
复制相似问题