<commit_before>object HLists {
  import Rank2Poly._
  
  sealed trait HList {
    type Tupled
    type Tupled1[A]
    type Tupled2[A, B]
    type Tupled3[A, B, C]
    type Tupled4[A, B, C, D]

    def tupled : Tupled
    def tupled1[A](a : A) : Tupled1[A]
    def tupled2[A, B](a : A, b : B) : Tupled2[A, B]
    def tupled3[A, B, C](a : A, b : B, c : C) : Tupled3[A, B, C]
    def tupled4[A, B, C, D](a : A, b : B, c : C, d : D) : Tupled4[A, B, C, D]
    
    type Fn[R]
    type Fn1[A, R]
    type Fn2[A, B, R]
    type Fn3[A, B, C, R]
    type Fn4[A, B, C, D, R]
  }
  
  final case class HCons[H, T <: HList](head : H, tail : T) extends HList {
    def ::[T](v : T) = HCons(v, this)
    override def toString = head+" :: "+tail.toString

    def map[F[_], G[_], Out <: HList](f : F ~> G)(implicit mapper : Mapper[F, G, H :: T, Out]) : Out = mapper(f, this)
    def map[F[_], OutH, OutT <: HList](f : F ~> Const[OutH]#λ)(implicit mapper : Mapper[F, Const[OutH]#λ, H :: T, OutH :: OutT]) : OutH :: OutT = mapper(f, this)
    
    type Tupled = T#Tupled1[H]
    type Tupled1[A] = T#Tupled2[A, H]
    type Tupled2[A, B] = T#Tupled3[A, B, H]
    type Tupled3[A, B, C] = T#Tupled4[A, B, C, H]
    type Tupled4[A, B, C, D] = Nothing

    def tupled : Tupled = tail.tupled1(head)
    def tupled1[A](a : A) : Tupled1[A] = tail.tupled2(a, head)
    def tupled2[A, B](a : A, b : B) : Tupled2[A, B] = tail.tupled3(a, b, head)
    def tupled3[A, B, C](a : A, b : B, c : C) : Tupled3[A, B, C] = tail.tupled4(a, b, c, head)
    def tupled4[A, B, C, D](a : A, b : B, c : C, d : D) : Tupled4[A, B, C, D] = sys.error("boom")

    type Fn[R] = T#Fn1[H, R]
    type Fn1[A, R] = T#Fn2[A, H, R]
    type Fn2[A, B, R] = T#Fn3[A, B, H, R]
    type Fn3[A, B, C, R] = T#Fn4[A, B, C, H, R]
    type Fn4[A, B, C, D, R] = Nothing
  }

  trait HNil extends HList {
    def ::[T](v : T) = HCons(v, this)
    override def toString = "HNil"

    def map[F](f : F) : HNil = HNil

    type Tupled = Nothing
    type Tupled1[A] = Tuple1[A]
    type Tupled2[A, B] = (A, B)
    type Tupled3[A, B, C] = (A, B, C)
    type Tupled4[A, B, C, D] = (A, B, C, D)

    def tupled : Tupled = sys.error("boom")
    def tupled1[A](a : A) : Tupled1[A] = Tuple1(a)
    def tupled2[A, B](a : A, b : B) : Tupled2[A, B] = (a, b)
    def tupled3[A, B, C](a : A, b : B, c : C) : Tupled3[A, B, C] = (a, b, c)
    def tupled4[A, B, C, D](a : A, b : B, c : C, d : D) : Tupled4[A, B, C, D] = (a, b, c, d)

    type Fn[R] = Nothing
    type Fn1[A, R] = A => R
    type Fn2[A, B, R] = (A, B) => R
    type Fn3[A, B, C, R] = (A, B, C) => R
    type Fn4[A, B, C, D, R] = (A, B, C, D) => R
  }
  
  case object HNil extends HNil
  
  type ::[H, T <: HList] = HCons[H, T]
  val :: = HCons

  type Applicator[F[_], G[_], In, Out] = (F ~> G, In) => Out

  implicit def applicator1[F[_], G[_], In] : Applicator[F, G, F[In], G[In]] = (f : F ~> G, t : F[In]) => f(t)
  
  implicit def applicator2[G[_], In] : Applicator[Id, G, In, G[In]] = (f : Id ~> G, t : In) => f(t)

  implicit def applicator3[F[_], In, Out] : Applicator[F, Const[Out]#λ, F[In], Out] = (f : F ~> Const[Out]#λ, t : F[In]) => f(t)

  trait Mapper[F[_], G[_], In <: HList, Out <: HList] {
    def apply(f : F ~> G, in: In) : Out
  }

  implicit def hnilMapper1[F[_], G[_]] = new Mapper[F, G, HNil, HNil] {
    def apply(f : F ~> G, l : HNil) = HNil
  }
  
  implicit def hnilMapper2[F[_], Out] = new Mapper[F, Const[Out]#λ, HNil, HNil] {
    def apply(f : F ~> Const[Out]#λ, l : HNil) = HNil
  }
  
  implicit def hlistMapper1[F[_], G[_], InH, OutH, InT <: HList, OutT <: HList]
    (implicit ap : Applicator[F, G, InH, OutH], mt : Mapper[F, G, InT, OutT]) = new Mapper[F, G, InH :: InT, OutH :: OutT] {<commit_msg>Use explicit type for applicator rather than function type to reduce risk of ambiguities.<commit_after>object HLists {
  import Rank2Poly._
  
  sealed trait HList {
    type Tupled
    type Tupled1[A]
    type Tupled2[A, B]
    type Tupled3[A, B, C]
    type Tupled4[A, B, C, D]

    def tupled : Tupled
    def tupled1[A](a : A) : Tupled1[A]
    def tupled2[A, B](a : A, b : B) : Tupled2[A, B]
    def tupled3[A, B, C](a : A, b : B, c : C) : Tupled3[A, B, C]
    def tupled4[A, B, C, D](a : A, b : B, c : C, d : D) : Tupled4[A, B, C, D]
    
    type Fn[R]
    type Fn1[A, R]
    type Fn2[A, B, R]
    type Fn3[A, B, C, R]
    type Fn4[A, B, C, D, R]
  }
  
  final case class HCons[H, T <: HList](head : H, tail : T) extends HList {
    def ::[T](v : T) = HCons(v, this)
    override def toString = head+" :: "+tail.toString

    def map[F[_], G[_], Out](f : F ~> G)(implicit mapper : Mapper[F, G, H :: T, Out]) : Out = mapper(f, this)
    def map[F[_], OutH, OutT <: HList](f : F ~> Const[OutH]#λ)(implicit mapper : Mapper[F, Const[OutH]#λ, H :: T, OutH :: OutT]) : OutH :: OutT = mapper(f, this)
    
    type Tupled = T#Tupled1[H]
    type Tupled1[A] = T#Tupled2[A, H]
    type Tupled2[A, B] = T#Tupled3[A, B, H]
    type Tupled3[A, B, C] = T#Tupled4[A, B, C, H]
    type Tupled4[A, B, C, D] = Nothing

    def tupled : Tupled = tail.tupled1(head)
    def tupled1[A](a : A) : Tupled1[A] = tail.tupled2(a, head)
    def tupled2[A, B](a : A, b : B) : Tupled2[A, B] = tail.tupled3(a, b, head)
    def tupled3[A, B, C](a : A, b : B, c : C) : Tupled3[A, B, C] = tail.tupled4(a, b, c, head)
    def tupled4[A, B, C, D](a : A, b : B, c : C, d : D) : Tupled4[A, B, C, D] = sys.error("boom")

    type Fn[R] = T#Fn1[H, R]
    type Fn1[A, R] = T#Fn2[A, H, R]
    type Fn2[A, B, R] = T#Fn3[A, B, H, R]
    type Fn3[A, B, C, R] = T#Fn4[A, B, C, H, R]
    type Fn4[A, B, C, D, R] = Nothing
  }

  trait HNil extends HList {
    def ::[T](v : T) = HCons(v, this)
    override def toString = "HNil"

    def map[F](f : F) : HNil = HNil

    type Tupled = Nothing
    type Tupled1[A] = Tuple1[A]
    type Tupled2[A, B] = (A, B)
    type Tupled3[A, B, C] = (A, B, C)
    type Tupled4[A, B, C, D] = (A, B, C, D)

    def tupled : Tupled = sys.error("boom")
    def tupled1[A](a : A) : Tupled1[A] = Tuple1(a)
    def tupled2[A, B](a : A, b : B) : Tupled2[A, B] = (a, b)
    def tupled3[A, B, C](a : A, b : B, c : C) : Tupled3[A, B, C] = (a, b, c)
    def tupled4[A, B, C, D](a : A, b : B, c : C, d : D) : Tupled4[A, B, C, D] = (a, b, c, d)

    type Fn[R] = Nothing
    type Fn1[A, R] = A => R
    type Fn2[A, B, R] = (A, B) => R
    type Fn3[A, B, C, R] = (A, B, C) => R
    type Fn4[A, B, C, D, R] = (A, B, C, D) => R
  }
  
  case object HNil extends HNil
  
  type ::[H, T <: HList] = HCons[H, T]
  val :: = HCons

  trait Applicator[F[_], G[_], In, Out] {
    def apply(f : F ~> G, in : In) : Out
  }

  implicit def applicator1[F[_], G[_], In] = new Applicator[F, G, F[In], G[In]] {
    def apply(f : F ~> G, t : F[In]) = f(t)
  }
  
  implicit def applicator2[G[_], In] = new Applicator[Id, G, In, G[In]] {
    def apply(f : Id ~> G, t : In) = f(t)
  }

  implicit def applicator3[F[_], In, Out] = new Applicator[F, Const[Out]#λ, F[In], Out] {
    def apply(f : F ~> Const[Out]#λ, t : F[In]) = f(t)
  }
  
  trait Mapper[F[_], G[_], In, Out] {
    def apply(f : F ~> G, in: In) : Out
  }

  implicit def hnilMapper1[F[_], G[_]] = new Mapper[F, G, HNil, HNil] {
    def apply(f : F ~> G, l : HNil) = HNil
  }
  
  implicit def hnilMapper2[F[_], Out] = new Mapper[F, Const[Out]#λ, HNil, HNil] {
    def apply(f : F ~> Const[Out]#λ, l : HNil) = HNil
  }
  
  implicit def hlistMapper1[F[_], G[_], InH, OutH, InT <: HList, OutT <: HList]
    (implicit ap : Applicator[F, G, InH, OutH], mt : Mapper[F, G, InT, OutT]) = new Mapper[F, G, InH :: InT, OutH :: OutT] {
{'fraction_non_alphanumeric': 0.20681908285978592, 'fraction_numerical': 0.0182370820668693, 'mean_word_length': 2.6279961649089167, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 33, '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': '4762545', 'n_tokens_mistral': 3679, 'n_tokens_neox': 3653, 'n_words': 1081}