+EitherOps, containing unmodified ApplicativeFunctor and EitherApplicativeFunctor from funcl
EitherOps: now contains EitherOps, and now compiles

-trait ApplicativeFunctor[A, M[A]] extends Functor[A, M] {
+trait EitherOps[L, R1] {

-class EitherApplicativeFunctor[A](eitherA: Either[_, A])
+object EitherOps {
EitherOps: minor renaming of arg passed to Left, Right

-      case (Left(x), _) => Left(x) // since, here, x is not of type A, and therefore may not be
+        case (Left(l), _) => Left(l)

-      case (Right(_), Left(x)) => Left(x)
+        case (Right(_), Left(l)) => Left(l)

-      case (Right(a), Right(f)) => Right(f(a))
+        case (Right(r1), Right(f)) => Right(f(r1))
Tests: + test("that substituting Left results in a Left") {
Tests: + test("combining checks on different types") {

   test("that substituting Left results in a Left") {
-    //case class CompoundValue(n: Int, b: Boolean, s: String)
qed: !EitherOps: f and either swapped places !Tests: + test("putting the function first") {

-trait EitherOps[L, R1] {
+trait EitherOps[L, R1, R2] {

-  def <*>[R2](f: Either[L, R1 => R2]): Either[L, R2]
+  def <*>(either: Either[L, R1]): Either[L, R2]

 object EitherOps {
-  implicit def either2EitherOps[L, R1](either: Either[L, R1]): EitherOps[L, R1] =
-    new EitherOps[L, R1] {
-      def <*>[R2](f: Either[L, R1 => R2]) = (either, f) match {
+  implicit def eitherOfFunction2EitherOps[L, R1, R2](f: Either[L, R1 => R2]): EitherOps[L, R1, R2] =
+    new EitherOps[L, R1, R2] {
+      def <*>(either: Either[L, R1]) = (f, either) match {

-        case (Right(r1), Right(f)) => Right(f(r1))
+        case (Right(f), Right(r1)) => Right(f(r1))

// test("that substituting Left results in a Left") {
// test("combining checks on different types") {
+  test("putting the function first") {
qed, where lift takes Left instance arg

 object EitherOps {
+  def lift[L, R1, R2](f: R1 => R2)(l: L) = Right[L, R1 => R2](f)

Tests
-    val n2b2s: Int => Boolean => String => CompoundValue = n => b => s => CompoundValue(n, b, s)
+    val n2b2s = (CompoundValue.apply _).curried

-    Right[String, Int => Boolean => String => CompoundValue](n2b2s) <*> checkPositive(n) <*>
+    lift(n2b2s)("") <*> checkPositive(n) <*>
Tests: case class now curried, so able to use CompoundValue.apply directly

-    case class CompoundValue(n: Int, b: Boolean, s: String)
+    case class CompoundValue(n: Int)(b: Boolean)(s: String)

-    lift(n2b2s)("") <*> checkPositive(n) <*>
+      lift(CompoundValue.apply)("") <*> checkPositive(n) <*> checkTrue(b) <*> checkNonEmpty(s)
qed, and works!

EitherOps
-trait EitherOps[L, R1, R2] {
-object EitherOps {

+class EitherOps[L] {
+  trait Enhancer[R1, R2] {

-  implicit def eitherOfFunction2EitherOps[L, R1, R2](f: Either[L, R1 => R2]): EitherOps[L, R1, R2] =
+  implicit def enhance[R1, R2](f: Either[L, R1 => R2]): Enhancer[R1, R2] = new Enhancer[R1, R2] {

Tests
-    import EitherOps._
+    object eitherOps extends EitherOps[String]
+    import eitherOps._

-      lift(CompoundValue.apply)("") <*> checkPositive(n) <*> checkTrue(b) <*> checkNonEmpty(s)
+      lift(CompoundValue.apply) <*> checkPositive(n) <*> checkTrue(b) <*> checkNonEmpty(s)
qed: first soln, duplicating everything, calling things *1, *2; bad data not yet tested

EitherOps
-  trait Enhancer[R1, R2] {
+  trait Enhancer1[R1, R2] {
     def <*>(either: Either[L, R1]): Either[L, R2]
+  trait Enhancer2[R1, R2] {
+    def <**>(either: Either[L, R1]): Either[List[L], R2]

-  def lift[R1, R2](f: R1 => R2) = Right[L, R1 => R2](f)
+  def lift1[R1, R2](f: R1 => R2) = Right[L,       R1 => R2](f)
+  def lift2[R1, R2](f: R1 => R2) = Right[List[L], R1 => R2](f)

-  implicit def enhance[R1, R2](f: Either[L, R1 => R2]): Enhancer[R1, R2] = new Enhancer[R1, R2] {
+  implicit def enhance1[R1, R2](f: Either[L, R1 => R2]): Enhancer1[R1, R2] =
+  implicit def enhance2[R1, R2](f: Either[List[L], R1 => R2]): Enhancer2[R1, R2] =

Tests
  test("putting the function first") {
-      lift(CompoundValue.apply) <*> checkPositive(n) <*> checkTrue(b) <*> checkNonEmpty(s)
+      lift1(CompoundValue.apply) <*> checkPositive(n) <*> checkTrue(b) <*> checkNonEmpty(s)

+  test("accumulating msgs in app-funct case") {
+      lift2(CompoundValue.apply) <**> checkPositive(n) <**> checkTrue(b) <**> checkNonEmpty(s)
'Left <**> Left' now APpends - less efficient, but msgs produced in right order; +EitherOpsTests

EitherOps
-        case (Left(ls), Left(l)) => Left(l::ls)
+        case (Left(ls), Left(l)) => Left(ls :+ l)
lift1=>fast lift2=>slow <**> => <*> !{EitherOps, EitherOpsTests}
contents of EitherOps class renamed, e.g. Enhancer1 becomes FastAppFunct; further doc-comments added

-  trait Enhancer1[R1, R2] {
+  trait FastAppFunct[R1, R2] {

-  trait Enhancer2[R1, R2] {
+  trait SlowAppFunct[R1, R2] {

-  implicit def enhance1[R1, R2](f: Either[L, R1 => R2]): Enhancer1[R1, R2] =
+  implicit def eitherFun2Fast[R1, R2](f: Either[L, R1 => R2]): FastAppFunct[R1, R2] =

-  implicit def enhance2[R1, R2](f: Either[List[L], R1 => R2]): Enhancer2[R1, R2] =
+  implicit def eitherFun2Slow[R1, R2](f: Either[List[L], R1 => R2]): SlowAppFunct[R1, R2] =
EitherExtras renamed Lift, and becomes an inner trait of EitherOps, which is renamed EitherExtras!
-EitherOps Tests=>LiftTests EitherOpsTests=>AppFunctTests
AppFunctTests: 'import EitherOps._'=>'import EitherExtras._'; "accumulating msgs"=>"fail-slow"
qed: check=>{fastCheck, slowCheck}, etc.; compiles

-    def check[L2](checks: ((T) => Either[L2, T])*): Either[List[L2], T]
+    /**
+     * as in fail-fast: returns at the first failure. */
+    def fastCheck[L2](checks: ((T) => Either[L2, T])*): Either[L2, T]
+    /**
+     * as in fail-slow: all checks are carried out. */
+    def slowCheck[L2](checks: ((T) => Either[L2, T])*): Either[List[L2], T]

-    def checkAndMap[L2, R](checks: ((T) => Either[L2, T])*)(f: (T) => R): Either[List[L2], R]
+    /**
+     * applies f if there were no failures. */
+    def fastCheckAndMap[L2, R](checks: ((T) => Either[L2, T])*)(f: (T) => R): Either[L2, R]
+    def slowCheckAndMap[L2, R](checks: ((T) => Either[L2, T])*)(f: (T) => R): Either[List[L2], R]
!{SaturdayNight, LiftTests}: check=>slowCheck
+AppFunctMeetsCheckTests: demos generating Records from lineInterator, but doesn't yet call checkFast/checkSlow
EitherExtras was a class - is now a trait; +UsingEither