I usually do the way @chi has done. As he stated, you can also you Template Haskell to do checks on the provided email at compile time. An example of doing that:
#!/usr/bin/env stack
{- stack
--resolver lts-8.2
exec ghci
--package email-validate
--package bytestring
-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE DeriveLift #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE QuasiQuotes #-}
import Language.Haskell.TH
import Language.Haskell.TH.Quote
import Language.Haskell.TH.Syntax
import Data.ByteString.Char8
import Text.Email.Validate
instance Lift ByteString where
lift b = [|pack $(lift $ unpack b)|]
instance Lift EmailAddress where
lift email = lift (toByteString email)
email :: QuasiQuoter
email =
QuasiQuoter
{ quoteExp =
\str ->
let (item :: EmailAddress) =
case (validate (pack str)) of
Left msg -> error msg
Right email -> email
in [|item|]
}
Now, if you load this up in ghci
:
> :set -XQuasiQuotes
> [email|sibi@mydomain.in|]
"sibi@mydomain.in"
> [email|invalidemail|]
:6:1: error:
• Exception when trying to run compile-time code:
@: not enough input
CallStack (from HasCallStack):
error, called at EmailV.hs:36:28 in main:EmailV
Code: quoteExp email "invalidemail"
• In the quasi-quotation: [email|invalidemail|]
You can see how you get compile error on the invalid input.