<commit_before>package scalaz.contrib

import scalaz._

import converter.Converter
import validator.Validator

object Checker {

  private[scalaz] def validatorsToSeq[F, T](t: T, vs: Seq[Validator[F, T]]) =
    vs.flatMap(_(t).toSeq).toVector

  def check[T](t: T): Checker[Nothing, T] =
    YesChecker(t, Vector.empty)

  def checkThat[F, T](t: T, vs: Validator[F, T]*): Checker[F, T] =
    YesChecker(t, validatorsToSeq(t, vs))

  def CheckerInstance[F]: Functor[({ type λ[α] = Checker[F, α] })#λ] = 
    new Functor[({ type λ[α] = Checker[F, α] })#λ] {
      def map[A, B](fa: Checker[F, A])(f: A => B) = fa map f
    }

}

sealed trait Checker[+F, T] {

  def checkThat[F1 >: F](vs: Validator[F1, T]*): Checker[F1, T]

  def convertTo[F1 >: F, U](conv: Converter[F1, T, U]): Checker[F1, U]

  def toValidation: Validation[NonEmptyList[F], T]

  def toOption = toValidation.toOption

  def map[U](f: T => U): Checker[F, U] = this match {
    case YesChecker(value, failures) => YesChecker(f(value), failures)
    case NoChecker(failures) => NoChecker(failures)
  }

}

private[scalaz] case class YesChecker[+F, T](value: T, failures: Vector[F]) extends Checker[F, T] {

  import Checker._

  def checkThat[F1 >: F](vs: Validator[F1, T]*) =
    YesChecker(value, failures ++ validatorsToSeq(value, vs))

  def convertTo[F1 >: F, U](conv: Converter[F1, T, U]) =
    failures match {
      case f +: fs => NoChecker(NonEmptyList(f, fs: _*))
      case _ => conv(value).fold(f => NoChecker(NonEmptyList(f)), YesChecker(_, Vector.empty))
    }

  def toValidation =
    failures match {
      case f +: fs => Failure(NonEmptyList(f, fs: _*))
      case _ => Success(value)
    }

}

private[scalaz] case class NoChecker[+F, T](failures: NonEmptyList[F]) extends Checker[F, T] {

  def checkThat[F1 >: F](vs: Validator[F1, T]*) =
    this

  def convertTo[F1 >: F, U](conv: Converter[F1, T, U]) =
    NoChecker(failures)

  def toValidation: Validation[NonEmptyList[F], T] =
    Failure(failures)

  override def toOption =
    None

}

// vim: expandtab:ts=2:sw=2<commit_msg>andAlso/andWith for Checker<commit_after>package scalaz.contrib

import scalaz._

import converter.Converter
import validator.Validator

object Checker {

  private[scalaz] def validatorsToSeq[F, T](t: T, vs: Seq[Validator[F, T]]) =
    vs.flatMap(_(t).toSeq).toVector

  def check[T](t: T): Checker[Nothing, T] =
    YesChecker(t, Vector.empty)

  def checkThat[F, T](t: T, vs: Validator[F, T]*): Checker[F, T] =
    YesChecker(t, validatorsToSeq(t, vs))

  def CheckerInstance[F]: Functor[({ type λ[α] = Checker[F, α] })#λ] = 
    new Functor[({ type λ[α] = Checker[F, α] })#λ] {
      def map[A, B](fa: Checker[F, A])(f: A => B) = fa map f
    }

}

sealed trait Checker[+F, T] {

  def checkThat[F1 >: F](vs: Validator[F1, T]*): Checker[F1, T]

  def convertTo[F1 >: F, U](conv: Converter[F1, T, U]): Checker[F1, U]

  def andAlso[F1 >: F, U](c: Checker[F1, U]): Checker[F1, (T, U)]

  @inline final def andWith[F1 >: F, U, R](that: Checker[F1, U], f: (T, U) => R) =
    this andAlso that map f.tupled

  def toValidation: Validation[NonEmptyList[F], T]

  def map[U](f: T => U): Checker[F, U]

  def toOption =
    toValidation.toOption

}

private[scalaz] case class YesChecker[+F, T](value: T, failures: Vector[F]) extends Checker[F, T] {

  import Checker._

  def checkThat[F1 >: F](vs: Validator[F1, T]*) =
    YesChecker(value, failures ++ validatorsToSeq(value, vs))

  def convertTo[F1 >: F, U](conv: Converter[F1, T, U]) =
    failures match {
      case f +: fs => NoChecker(NonEmptyList(f, fs: _*))
      case _ => conv(value).fold(f => NoChecker(NonEmptyList(f)), YesChecker(_, Vector.empty))
    }

  def andAlso[F1 >: F, U](c: Checker[F1, U]) =
    c match {
      case YesChecker(v, fs) => YesChecker((value, v), failures ++ fs)
      case NoChecker(fs) => NoChecker(failures.toList <::: fs)
    }

  def toValidation =
    failures match {
      case f +: fs => Failure(NonEmptyList(f, fs: _*))
      case _ => Success(value)
    }

  def map[U](f: T => U): Checker[F, U] =
    YesChecker(f(value), failures)

}

private[scalaz] case class NoChecker[+F, T](failures: NonEmptyList[F]) extends Checker[F, T] {

  def checkThat[F1 >: F](vs: Validator[F1, T]*) =
    this

  def convertTo[F1 >: F, U](conv: Converter[F1, T, U]) =
    NoChecker(failures)

  def andAlso[F1 >: F, U](c: Checker[F1, U]) =
    c match {
      case YesChecker(v, fs) => NoChecker(failures :::> fs.toList)
      case NoChecker(fs) => NoChecker(failures append fs)
    }

  def toValidation: Validation[NonEmptyList[F], T] =
    Failure(failures)

  def map[U](f: T => U): Checker[F, U] =
    NoChecker(failures)

  override def toOption =
    None

}

// vim: expandtab:ts=2:sw=2
{'fraction_non_alphanumeric': 0.17425200168563001, 'fraction_numerical': 0.008638853771597134, 'mean_word_length': 3.7660642570281126, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1444983', 'n_tokens_mistral': 1921, 'n_tokens_neox': 1890, 'n_words': 454}