首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在数据验证中使用“任一”

在数据验证中使用“任一”
EN

Stack Overflow用户
提问于 2019-05-29 23:06:59
回答 1查看 226关注 0票数 1

我有一个程序,这是专门创建“学生”(名字,姓氏,年龄)和验证输入数据。我的问题是:当我插入学生时,例如名字不是2个字母或者年龄小于18岁-程序只显示一个错误。如何使用“任一函数”创建一个包含所有错误的字符串?

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

发布于 2019-05-29 23:18:27

一种简单的解决方法是将左侧的Either更改为自定义数据类型。我的意思是,您可以使用Either ErrorType Age代替Either String Age,然后定义

代码语言:javascript
复制
data ErrorType = LowAge | WrongName

在我看来,这也是更好的编程实践,因为您可以将错误抛出和它的处理程序分开。特别是在Haskell和函数式编程中,我不会随身携带字符串表示来处理错误。然后,例如,您可以将错误组合到一个列表中,即:

代码语言:javascript
复制
mkStudent :: String -> String -> String -> Either [ErrorType] Student

然后,只需使用另一个函数来处理列表并将其打印给用户,或记录该列表,或执行您想要对其执行的任何操作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56363625

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档