我有一个scala (2.10.4)应用程序,其中电子邮件地址被大量传递,我想实现一个在IO调用的抽象来“清理”已经验证的电子邮件地址。
使用scala.Proxy几乎就是我想要的,但是我遇到了不对称相等的问题。
class SanitizedEmailAddress(s: String) extends Proxy with Ordered[SanitizedEmailAddress] {
val self: String = s.toLowerCase.trim
def compare(that: SanitizedEmailAddress) = self compareTo that.self
}
object SanitizedEmailAddress {
def apply(s: String) = new SanitizedEmailAddress(s)
implicit def sanitize(s: String): SanitizedEmailAddress = new SanitizedEmailAddress(s)
implicit def underlying(e: SanitizedEmailAddress): String = e.self
}我想要一份
val sanitizedEmail = SanitizedEmailAddress("Blah@Blah.com")
val expected = "blah@blah.com"
assert(sanitizedEmail == expected) // => true
assert(expected == sanitizedEmail) // => true, but this currently returns false :(或者具有类似功能的东西。有什么不麻烦的方法可以做到这一点吗?
assert(sanitizedEmail.self == expected) // => true (but pretty bad, and someone will forget)
// can have a custom equality method and use the "pimp-my-lib" pattern on strings, but then we have to remember to use that method every time谢谢你的帮助。
发布于 2017-02-08 03:13:16
您希望使用标记特征来表示符合的字符串。
接受Email字符串的函数知道该字符串是正确的。
如果将普通字符串与Email字符串进行比较,则它也必须是正确的。
package object email {
type Tagged[U] = { type Tag = U }
type @@[T, U] = T with Tagged[U]
def smartly[A](s: String): String @@ A = Email(s).asInstanceOf[String @@ A]
}
package email {
trait Email extends Any
object Email {
def apply(s: String) = s.toLowerCase.trim
}
object Test extends App {
def f(ok: String @@ Email) = {
assert(ok.forall(c => !c.isLetter || c.isLower))
}
val x = smartly[Email]("Joe@ACME.com")
println(x)
f(x)
assert("joe@acme.com" == x)
/*
f("Junk@Yahoo.com") // DNC
email.scala:22: error: type mismatch;
found : String("Junk@Yahoo.com")
required: email.@@[String,email.Email]
(which expands to) String with AnyRef{type Tag = email.Email}
f("Junk@Yahoo.com")
^
one error found
*/
}
} https://stackoverflow.com/questions/41707483
复制相似问题