我想知道为什么email-validate包在以下代码中派生出Eq:
data EmailAddress = EmailAddress ByteString ByteString
deriving (Eq, Ord, Data, Typeable, Generic)
我的意思是,我使用Text
用于电子邮件地址,直到我意识到我需要让它们不区分大小写(因此我不会将Example@ex.ample
和example@ex.ample
保存为2不同的地址),所以我到这个库只发现它派生Eq
。
那么,派生Eq
而不是自制的不区分大小写的实例是否合理?
另外,如果我要使用此库,我如何为Eq
提供自己的EmailAdress
实例?
答案 0 :(得分:13)
那么,派生
Eq
而不是自制的不区分大小写的实例是否合理?
那取决于你想要什么。我确定该软件包的作者有他们Eq
实例的原因。
此外,如果我要使用此库,我如何为
Eq
提供我自己的EmailAdress
实例?
你无法覆盖"他们的实例。这类问题的通常解决方案是newtype
包装器,您可以在其上编写自己的实例:
newtype MyEmailAddress = MyEmailAddress EmailAddress
然后你可以自由定义你自己的平等版本,可能是:
import Data.Char (toLower)
import qualified Data.ByteString.Char8 as DBC (map)
instance Eq MyEmailAddress where
MyEmailAddress (EmailAddress a1 d1) == MyEmailAddress (EmailAddress a2 d2)
= DBC.map toLower a1 == DBC.map toLower a2 && DBC.map toLower d1 == DBC.map toLower d2
虽然我在谈论它,但请允许我提一下你甚至可以定义一个模式同义词,它可以让一切变得更好:
{-# LANGUAGE PatternSynonyms #-}
pattern Email address domain = MyEmailAddress (EmailAddress address domain)
然后,您可以使用Email "yourName" "yourDomain"
轻松制作一封电子邮件,并在其上进行模式匹配。 Eq
实例看起来好多了:
instance Eq MyEmailAddress where
Email a1 d1 == Email a2 d2
= DBC.map toLower a1 == DBC.map toLower a2 && DBC.map toLower d1 == DBC.map toLower d2