Uniformity

trait Uniformity[A] extends Normalization[A]

Defines a custom way to normalize instances of a type that can also handle normalization of that type when passed as Any.

For example, to normalize Doubles by truncating off any decimal part, you might write:

import org.scalactic._

val truncated =
 new Uniformity[Double] {
  def normalized(d: Double) = d.floor
  def normalizedCanHandle(o: Any) = o.isInstanceOf[Double]
  def normalizedOrSame(o: Any): Any =
    o match {
      case d: Double => normalized(d)
      case _ => o
    }
}

Given this definition you could use it with the Explicitly DSL like this:

import org.scalatest._
import Matchers._

2.1 should equal (2.0) (after being truncated)

If you make the truncated val implicit and import or mix in the members of NormMethods, you can access the behavior by invoking .norm on Doubles.

implicit val doubleUniformity = truncated
import NormMethods._

val d = 2.1
d.norm // returns 2.0

Note that by creating a Uniformity rather than just an instance of its supertype, Normalization, it can be used more generally. For example, Uniformitys allow you to the Explicitly DSL with TripleEquals, whereas Normalizations require TypeCheckedTripleEquals. Uniformitys also enable you to use the Explicitly DSL with ScalaTest's should ===, equal, and contain matcher syntax, whereas a plain Normalization can only be used with should ===, and only under TypeCheckedTripleEquals.

Type parameters:
A

the type whose uniformity is being defined

Source:
Uniformity.scala
trait Normalization[A]
class Object
trait Matchable
class Any

Value members

Abstract methods

def normalizedCanHandle(b: Any): Boolean

Indicates whether this Uniformity's normalized method can “handle” the passed object, if cast to the appropriate type A.

Indicates whether this Uniformity's normalized method can “handle” the passed object, if cast to the appropriate type A.

If this method returns true for a particular passed object, it means that if the object is passed to normalizedOrSame, that method will return the result of passing it to normalized. It does not mean that the object will necessarily be modified when passed to normalizedOrSame or normalized. For example, the lowerCased field of StringNormalizations is a Uniformity[String] that normalizes strings by forcing all characters to lower case:

scala> import org.scalactic._
import org.scalactic._

scala> import StringNormalizations._
import StringNormalizations._

scala> lowerCased
res0: org.scalactic.Uniformity[String] = lowerCased

scala> lowerCased.normalized("HALLOOO!")
res1: String = hallooo!

Now consider two strings held from variables of type AnyRef:

scala> val yell: AnyRef = "HOWDY"
yell: AnyRef = HOWDY

scala> val whisper: AnyRef = "howdy"
whisper: AnyRef = howdy

As you would expect, when yell is passed to normalizedCanHandle, it returns true, and when yell is passed to normalizedOrSame, it returns a lower-cased (normal) form:

scala> lowerCased.normalizedCanHandle(yell)
res2: Boolean = true

scala> lowerCased.normalizedOrSame(yell)
res3: Any = howdy

A similar thing happens, however, when whisper is passed to normalizedCanHandle and normalizedOrSame, even though in this case the string is already in normal form according to the lowerCased Uniformity:

scala> lowerCased.normalizedCanHandle(whisper)
res4: Boolean = true

scala> lowerCased.normalizedOrSame(whisper)
res5: Any = howdy

This illustrates that normalizedCanHandle does not indicate that the passed object is not in normalized form already, just that it can be be handled by the normalized method. This further means that the normalized method itself simply ensures that objects are returned in normal form. It need not necessarily change them: if a passed object is already in normal form, normalized can (and usually should) return the exact same object. That is in fact what happened when we normalized whisper. Since whisper's value of "hello" was already in normal form (all lower-cased), normalized ( invoked by the normalizedOrSame method) returned the exact same object passed:

scala> val whisperNormed = res5.asInstanceOf[AnyRef]
whisperNormed: AnyRef = howdy

scala> whisperNormed eq whisper
res8: Boolean = true
Source:
Uniformity.scala
def normalizedOrSame(b: Any): Any

Returns either the result of passing this object to normalized, if appropriate, or the same object.

Returns either the result of passing this object to normalized, if appropriate, or the same object.

Implementations can decide what “appropriate” means, but the intent is that it will usually mean the value passed is of the type A. For example, if this is a Uniformity[String], appropriate means that the value (of type Any) passed is actually an instance of String. Because of erasure, however, a Uniformity[List[String]] will only be able to tell whether a value is a List[_], so it might declare any List[_] that contains only Strings (determined by invoking isInstanceOf[String] on each element) to be appropriate. This means a Uniformity[List[String]] might normalize a List[AnyRef] that happens to contain only Strings.

Value parameters:
b

the object to normalize, if appropriate

Returns:

a normalized form of the passed object, if this Uniformity was able to normalize it, else the same object passed

Source:
Uniformity.scala

Concrete methods

final def and(other: Uniformity[A]): Uniformity[A]

Returns a new Uniformity that combines this and the passed Uniformity.

Returns a new Uniformity that combines this and the passed Uniformity.

The normalized and normalizedOrSame methods of the Uniformity returned by this method return a result obtained by forwarding the passed value first to this Uniformity's implementation of the method, then passing that result to the other Uniformity's implementation of the method, respectively. Essentially, the body of the composed normalized method is:

uniformityPassedToAnd.normalized(uniformityOnWhichAndWasInvoked.normalized(a))

And the body of the composed normalizedOrSame method is:

uniformityPassedToAnd.normalizedOrSame(uniformityOnWhichAndWasInvoked.normalizedOrSame(a))

The normalizeCanHandle method of the Uniformity returned by this method returns a result obtained by anding the result of forwarding the passed value to this Uniformity's implementation of the method with the result of forwarding it to the passed Uniformity's implementation. Essentially, the body of the composed normalizeCanHandle method is:

uniformityOnWhichAndWasInvoked.normalizeCanHandle(a) && uniformityPassedToAnd.normalizeCanHandle(a)
Value parameters:
other

a Uniformity to 'and' with this one

Returns:

a Uniformity representing the composition of this and the passed Uniformity

Source:
Uniformity.scala
final def toEquality(implicit equality: Equality[A]): NormalizingEquality[A]

Converts this Uniformity to a NormalizingEquality[A] whose normalized, normalizedCanHandle, and normalizedOrSame methods delegate to this Uniformity[A] and whose afterNormalizationEquality field returns the implicitly passed Equality[A].

Converts this Uniformity to a NormalizingEquality[A] whose normalized, normalizedCanHandle, and normalizedOrSame methods delegate to this Uniformity[A] and whose afterNormalizationEquality field returns the implicitly passed Equality[A].

Value parameters:
equality

the Equality that the returned NormalizingEquality will delegate to determine equality after normalizing both left and right (if appropriate) sides.

Source:
Uniformity.scala

Inherited methods

final def and(other: Normalization[A]): Normalization[A]

Returns a new Normalization that composes this and the passed Normalization.

Returns a new Normalization that composes this and the passed Normalization.

The normalized method of the Normalization returned by this method returns a normalized form of the passed object obtained by forwarding the passed value first to this Normalization's normalized method, then passing that result to the other Normalization's normalized method. Essentially, the body of the composed normalized method is:

normalizationPassedToAnd.normalized(normalizationOnWhichAndWasInvoked.normalized(a))
Value parameters:
other

a Normalization to 'and' with this one

Returns:

a Normalization representing the composition of this and the passed Normalization

Inherited from:
Normalization
Source:
Normalization.scala
def normalized(a: A): A

Returns a normalized form of the passed object.

Returns a normalized form of the passed object.

If the passed object is already in normal form, this method may return the same instance passed.

Type parameters:
A

the type of the object to normalize

Value parameters:
a

the object to normalize

Returns:

the normalized form of the passed object

Inherited from:
Normalization
Source:
Normalization.scala
final def toEquivalence(implicit equivalence: Equivalence[A]): NormalizingEquivalence[A]

Converts this Normalization to a NormalizingEquivalence[A] whose normalized method delegates to this Normalization[A] and whose afterNormalizationEquivalence field returns the implicitly passed Equivalence[A].

Converts this Normalization to a NormalizingEquivalence[A] whose normalized method delegates to this Normalization[A] and whose afterNormalizationEquivalence field returns the implicitly passed Equivalence[A].

Value parameters:
equivalence

the Equivalence that the returned NormalizingEquivalence will delegate to determine equality after normalizing both left and right (if appropriate) sides.

Inherited from:
Normalization
Source:
Normalization.scala