// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2024-02-29 16:19:31.6574369 +0100 CET m=+0.012049601

package tuple

import (
	M "github.com/IBM/fp-go/monoid"
	O "github.com/IBM/fp-go/ord"
)

// Tuple1 is a struct that carries 1 independently typed values
type Tuple1[T1 any] struct {
	F1 T1
}

// Tuple2 is a struct that carries 2 independently typed values
type Tuple2[T1, T2 any] struct {
	F1 T1
	F2 T2
}

// Tuple3 is a struct that carries 3 independently typed values
type Tuple3[T1, T2, T3 any] struct {
	F1 T1
	F2 T2
	F3 T3
}

// Tuple4 is a struct that carries 4 independently typed values
type Tuple4[T1, T2, T3, T4 any] struct {
	F1 T1
	F2 T2
	F3 T3
	F4 T4
}

// Tuple5 is a struct that carries 5 independently typed values
type Tuple5[T1, T2, T3, T4, T5 any] struct {
	F1 T1
	F2 T2
	F3 T3
	F4 T4
	F5 T5
}

// Tuple6 is a struct that carries 6 independently typed values
type Tuple6[T1, T2, T3, T4, T5, T6 any] struct {
	F1 T1
	F2 T2
	F3 T3
	F4 T4
	F5 T5
	F6 T6
}

// Tuple7 is a struct that carries 7 independently typed values
type Tuple7[T1, T2, T3, T4, T5, T6, T7 any] struct {
	F1 T1
	F2 T2
	F3 T3
	F4 T4
	F5 T5
	F6 T6
	F7 T7
}

// Tuple8 is a struct that carries 8 independently typed values
type Tuple8[T1, T2, T3, T4, T5, T6, T7, T8 any] struct {
	F1 T1
	F2 T2
	F3 T3
	F4 T4
	F5 T5
	F6 T6
	F7 T7
	F8 T8
}

// Tuple9 is a struct that carries 9 independently typed values
type Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any] struct {
	F1 T1
	F2 T2
	F3 T3
	F4 T4
	F5 T5
	F6 T6
	F7 T7
	F8 T8
	F9 T9
}

// Tuple10 is a struct that carries 10 independently typed values
type Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any] struct {
	F1  T1
	F2  T2
	F3  T3
	F4  T4
	F5  T5
	F6  T6
	F7  T7
	F8  T8
	F9  T9
	F10 T10
}

// Tuple11 is a struct that carries 11 independently typed values
type Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 any] struct {
	F1  T1
	F2  T2
	F3  T3
	F4  T4
	F5  T5
	F6  T6
	F7  T7
	F8  T8
	F9  T9
	F10 T10
	F11 T11
}

// Tuple12 is a struct that carries 12 independently typed values
type Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 any] struct {
	F1  T1
	F2  T2
	F3  T3
	F4  T4
	F5  T5
	F6  T6
	F7  T7
	F8  T8
	F9  T9
	F10 T10
	F11 T11
	F12 T12
}

// Tuple13 is a struct that carries 13 independently typed values
type Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 any] struct {
	F1  T1
	F2  T2
	F3  T3
	F4  T4
	F5  T5
	F6  T6
	F7  T7
	F8  T8
	F9  T9
	F10 T10
	F11 T11
	F12 T12
	F13 T13
}

// Tuple14 is a struct that carries 14 independently typed values
type Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 any] struct {
	F1  T1
	F2  T2
	F3  T3
	F4  T4
	F5  T5
	F6  T6
	F7  T7
	F8  T8
	F9  T9
	F10 T10
	F11 T11
	F12 T12
	F13 T13
	F14 T14
}

// Tuple15 is a struct that carries 15 independently typed values
type Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 any] struct {
	F1  T1
	F2  T2
	F3  T3
	F4  T4
	F5  T5
	F6  T6
	F7  T7
	F8  T8
	F9  T9
	F10 T10
	F11 T11
	F12 T12
	F13 T13
	F14 T14
	F15 T15
}

// MakeTuple1 is a function that converts its 1 parameters into a [Tuple1]
func MakeTuple1[T1 any](t1 T1) Tuple1[T1] {
	return Tuple1[T1]{t1}
}

// Tupled1 converts a function with 1 parameters into a function taking a Tuple1
// The inverse function is [Untupled1]
func Tupled1[F ~func(T1) R, T1, R any](f F) func(Tuple1[T1]) R {
	return func(t Tuple1[T1]) R {
		return f(t.F1)
	}
}

// Untupled1 converts a function with a [Tuple1] parameter into a function with 1 parameters
// The inverse function is [Tupled1]
func Untupled1[F ~func(Tuple1[T1]) R, T1, R any](f F) func(T1) R {
	return func(t1 T1) R {
		return f(MakeTuple1(t1))
	}
}

// Monoid1 creates a [Monoid] for a [Tuple1] based on 1 monoids for the contained types
func Monoid1[T1 any](m1 M.Monoid[T1]) M.Monoid[Tuple1[T1]] {
	return M.MakeMonoid(func(l, r Tuple1[T1]) Tuple1[T1] {
		return MakeTuple1(m1.Concat(l.F1, r.F1))
	}, MakeTuple1(m1.Empty()))
}

// Ord1 creates n [Ord] for a [Tuple1] based on 1 [Ord]s for the contained types
func Ord1[T1 any](o1 O.Ord[T1]) O.Ord[Tuple1[T1]] {
	return O.MakeOrd(func(l, r Tuple1[T1]) int {
		if c := o1.Compare(l.F1, r.F1); c != 0 {
			return c
		}
		return 0
	}, func(l, r Tuple1[T1]) bool {
		return o1.Equals(l.F1, r.F1)
	})
}

// Map1 maps each value of a [Tuple1] via a mapping function
func Map1[F1 ~func(T1) R1, T1, R1 any](f1 F1) func(Tuple1[T1]) Tuple1[R1] {
	return func(t Tuple1[T1]) Tuple1[R1] {
		return MakeTuple1(
			f1(t.F1),
		)
	}
}

// Replicate1 creates a [Tuple1] with all fields set to the input value `t`
func Replicate1[T any](t T) Tuple1[T] {
	return MakeTuple1(t)
}

// String prints some debug info for the [Tuple1]
func (t Tuple1[T1]) String() string {
	return tupleString(t.F1)
}

// MarshalJSON marshals the [Tuple1] into a JSON array
func (t Tuple1[T1]) MarshalJSON() ([]byte, error) {
	return tupleMarshalJSON(t.F1)
}

// UnmarshalJSON unmarshals a JSON array into a [Tuple1]
func (t *Tuple1[T1]) UnmarshalJSON(data []byte) error {
	return tupleUnmarshalJSON(data, &t.F1)
}

// ToArray converts the [Tuple1] into an array of type [R] using 1 transformation functions from [T] to [R]
// The inverse function is [FromArray1]
func ToArray1[F1 ~func(T1) R, T1, R any](f1 F1) func(t Tuple1[T1]) []R {
	return func(t Tuple1[T1]) []R {
		return []R{
			f1(t.F1),
		}
	}
}

// FromArray converts an array of [R] into a [Tuple1] using 1 functions from [R] to [T]
// The inverse function is [ToArray1]
func FromArray1[F1 ~func(R) T1, T1, R any](f1 F1) func(r []R) Tuple1[T1] {
	return func(r []R) Tuple1[T1] {
		return MakeTuple1(
			f1(r[0]),
		)
	}
}

// Push1 creates a [Tuple2] from a [Tuple1] by appending a constant value
func Push1[T1, T2 any](value T2) func(Tuple1[T1]) Tuple2[T1, T2] {
	return func(t Tuple1[T1]) Tuple2[T1, T2] {
		return MakeTuple2(t.F1, value)
	}
}

// MakeTuple2 is a function that converts its 2 parameters into a [Tuple2]
func MakeTuple2[T1, T2 any](t1 T1, t2 T2) Tuple2[T1, T2] {
	return Tuple2[T1, T2]{t1, t2}
}

// Tupled2 converts a function with 2 parameters into a function taking a Tuple2
// The inverse function is [Untupled2]
func Tupled2[F ~func(T1, T2) R, T1, T2, R any](f F) func(Tuple2[T1, T2]) R {
	return func(t Tuple2[T1, T2]) R {
		return f(t.F1, t.F2)
	}
}

// Untupled2 converts a function with a [Tuple2] parameter into a function with 2 parameters
// The inverse function is [Tupled2]
func Untupled2[F ~func(Tuple2[T1, T2]) R, T1, T2, R any](f F) func(T1, T2) R {
	return func(t1 T1, t2 T2) R {
		return f(MakeTuple2(t1, t2))
	}
}

// Monoid2 creates a [Monoid] for a [Tuple2] based on 2 monoids for the contained types
func Monoid2[T1, T2 any](m1 M.Monoid[T1], m2 M.Monoid[T2]) M.Monoid[Tuple2[T1, T2]] {
	return M.MakeMonoid(func(l, r Tuple2[T1, T2]) Tuple2[T1, T2] {
		return MakeTuple2(m1.Concat(l.F1, r.F1), m2.Concat(l.F2, r.F2))
	}, MakeTuple2(m1.Empty(), m2.Empty()))
}

// Ord2 creates n [Ord] for a [Tuple2] based on 2 [Ord]s for the contained types
func Ord2[T1, T2 any](o1 O.Ord[T1], o2 O.Ord[T2]) O.Ord[Tuple2[T1, T2]] {
	return O.MakeOrd(func(l, r Tuple2[T1, T2]) int {
		if c := o1.Compare(l.F1, r.F1); c != 0 {
			return c
		}
		if c := o2.Compare(l.F2, r.F2); c != 0 {
			return c
		}
		return 0
	}, func(l, r Tuple2[T1, T2]) bool {
		return o1.Equals(l.F1, r.F1) && o2.Equals(l.F2, r.F2)
	})
}

// Map2 maps each value of a [Tuple2] via a mapping function
func Map2[F1 ~func(T1) R1, F2 ~func(T2) R2, T1, R1, T2, R2 any](f1 F1, f2 F2) func(Tuple2[T1, T2]) Tuple2[R1, R2] {
	return func(t Tuple2[T1, T2]) Tuple2[R1, R2] {
		return MakeTuple2(
			f1(t.F1),
			f2(t.F2),
		)
	}
}

// Replicate2 creates a [Tuple2] with all fields set to the input value `t`
func Replicate2[T any](t T) Tuple2[T, T] {
	return MakeTuple2(t, t)
}

// String prints some debug info for the [Tuple2]
func (t Tuple2[T1, T2]) String() string {
	return tupleString(t.F1, t.F2)
}

// MarshalJSON marshals the [Tuple2] into a JSON array
func (t Tuple2[T1, T2]) MarshalJSON() ([]byte, error) {
	return tupleMarshalJSON(t.F1, t.F2)
}

// UnmarshalJSON unmarshals a JSON array into a [Tuple2]
func (t *Tuple2[T1, T2]) UnmarshalJSON(data []byte) error {
	return tupleUnmarshalJSON(data, &t.F1, &t.F2)
}

// ToArray converts the [Tuple2] into an array of type [R] using 2 transformation functions from [T] to [R]
// The inverse function is [FromArray2]
func ToArray2[F1 ~func(T1) R, F2 ~func(T2) R, T1, T2, R any](f1 F1, f2 F2) func(t Tuple2[T1, T2]) []R {
	return func(t Tuple2[T1, T2]) []R {
		return []R{
			f1(t.F1),
			f2(t.F2),
		}
	}
}

// FromArray converts an array of [R] into a [Tuple2] using 2 functions from [R] to [T]
// The inverse function is [ToArray2]
func FromArray2[F1 ~func(R) T1, F2 ~func(R) T2, T1, T2, R any](f1 F1, f2 F2) func(r []R) Tuple2[T1, T2] {
	return func(r []R) Tuple2[T1, T2] {
		return MakeTuple2(
			f1(r[0]),
			f2(r[1]),
		)
	}
}

// Push2 creates a [Tuple3] from a [Tuple2] by appending a constant value
func Push2[T1, T2, T3 any](value T3) func(Tuple2[T1, T2]) Tuple3[T1, T2, T3] {
	return func(t Tuple2[T1, T2]) Tuple3[T1, T2, T3] {
		return MakeTuple3(t.F1, t.F2, value)
	}
}

// MakeTuple3 is a function that converts its 3 parameters into a [Tuple3]
func MakeTuple3[T1, T2, T3 any](t1 T1, t2 T2, t3 T3) Tuple3[T1, T2, T3] {
	return Tuple3[T1, T2, T3]{t1, t2, t3}
}

// Tupled3 converts a function with 3 parameters into a function taking a Tuple3
// The inverse function is [Untupled3]
func Tupled3[F ~func(T1, T2, T3) R, T1, T2, T3, R any](f F) func(Tuple3[T1, T2, T3]) R {
	return func(t Tuple3[T1, T2, T3]) R {
		return f(t.F1, t.F2, t.F3)
	}
}

// Untupled3 converts a function with a [Tuple3] parameter into a function with 3 parameters
// The inverse function is [Tupled3]
func Untupled3[F ~func(Tuple3[T1, T2, T3]) R, T1, T2, T3, R any](f F) func(T1, T2, T3) R {
	return func(t1 T1, t2 T2, t3 T3) R {
		return f(MakeTuple3(t1, t2, t3))
	}
}

// Monoid3 creates a [Monoid] for a [Tuple3] based on 3 monoids for the contained types
func Monoid3[T1, T2, T3 any](m1 M.Monoid[T1], m2 M.Monoid[T2], m3 M.Monoid[T3]) M.Monoid[Tuple3[T1, T2, T3]] {
	return M.MakeMonoid(func(l, r Tuple3[T1, T2, T3]) Tuple3[T1, T2, T3] {
		return MakeTuple3(m1.Concat(l.F1, r.F1), m2.Concat(l.F2, r.F2), m3.Concat(l.F3, r.F3))
	}, MakeTuple3(m1.Empty(), m2.Empty(), m3.Empty()))
}

// Ord3 creates n [Ord] for a [Tuple3] based on 3 [Ord]s for the contained types
func Ord3[T1, T2, T3 any](o1 O.Ord[T1], o2 O.Ord[T2], o3 O.Ord[T3]) O.Ord[Tuple3[T1, T2, T3]] {
	return O.MakeOrd(func(l, r Tuple3[T1, T2, T3]) int {
		if c := o1.Compare(l.F1, r.F1); c != 0 {
			return c
		}
		if c := o2.Compare(l.F2, r.F2); c != 0 {
			return c
		}
		if c := o3.Compare(l.F3, r.F3); c != 0 {
			return c
		}
		return 0
	}, func(l, r Tuple3[T1, T2, T3]) bool {
		return o1.Equals(l.F1, r.F1) && o2.Equals(l.F2, r.F2) && o3.Equals(l.F3, r.F3)
	})
}

// Map3 maps each value of a [Tuple3] via a mapping function
func Map3[F1 ~func(T1) R1, F2 ~func(T2) R2, F3 ~func(T3) R3, T1, R1, T2, R2, T3, R3 any](f1 F1, f2 F2, f3 F3) func(Tuple3[T1, T2, T3]) Tuple3[R1, R2, R3] {
	return func(t Tuple3[T1, T2, T3]) Tuple3[R1, R2, R3] {
		return MakeTuple3(
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
		)
	}
}

// Replicate3 creates a [Tuple3] with all fields set to the input value `t`
func Replicate3[T any](t T) Tuple3[T, T, T] {
	return MakeTuple3(t, t, t)
}

// String prints some debug info for the [Tuple3]
func (t Tuple3[T1, T2, T3]) String() string {
	return tupleString(t.F1, t.F2, t.F3)
}

// MarshalJSON marshals the [Tuple3] into a JSON array
func (t Tuple3[T1, T2, T3]) MarshalJSON() ([]byte, error) {
	return tupleMarshalJSON(t.F1, t.F2, t.F3)
}

// UnmarshalJSON unmarshals a JSON array into a [Tuple3]
func (t *Tuple3[T1, T2, T3]) UnmarshalJSON(data []byte) error {
	return tupleUnmarshalJSON(data, &t.F1, &t.F2, &t.F3)
}

// ToArray converts the [Tuple3] into an array of type [R] using 3 transformation functions from [T] to [R]
// The inverse function is [FromArray3]
func ToArray3[F1 ~func(T1) R, F2 ~func(T2) R, F3 ~func(T3) R, T1, T2, T3, R any](f1 F1, f2 F2, f3 F3) func(t Tuple3[T1, T2, T3]) []R {
	return func(t Tuple3[T1, T2, T3]) []R {
		return []R{
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
		}
	}
}

// FromArray converts an array of [R] into a [Tuple3] using 3 functions from [R] to [T]
// The inverse function is [ToArray3]
func FromArray3[F1 ~func(R) T1, F2 ~func(R) T2, F3 ~func(R) T3, T1, T2, T3, R any](f1 F1, f2 F2, f3 F3) func(r []R) Tuple3[T1, T2, T3] {
	return func(r []R) Tuple3[T1, T2, T3] {
		return MakeTuple3(
			f1(r[0]),
			f2(r[1]),
			f3(r[2]),
		)
	}
}

// Push3 creates a [Tuple4] from a [Tuple3] by appending a constant value
func Push3[T1, T2, T3, T4 any](value T4) func(Tuple3[T1, T2, T3]) Tuple4[T1, T2, T3, T4] {
	return func(t Tuple3[T1, T2, T3]) Tuple4[T1, T2, T3, T4] {
		return MakeTuple4(t.F1, t.F2, t.F3, value)
	}
}

// MakeTuple4 is a function that converts its 4 parameters into a [Tuple4]
func MakeTuple4[T1, T2, T3, T4 any](t1 T1, t2 T2, t3 T3, t4 T4) Tuple4[T1, T2, T3, T4] {
	return Tuple4[T1, T2, T3, T4]{t1, t2, t3, t4}
}

// Tupled4 converts a function with 4 parameters into a function taking a Tuple4
// The inverse function is [Untupled4]
func Tupled4[F ~func(T1, T2, T3, T4) R, T1, T2, T3, T4, R any](f F) func(Tuple4[T1, T2, T3, T4]) R {
	return func(t Tuple4[T1, T2, T3, T4]) R {
		return f(t.F1, t.F2, t.F3, t.F4)
	}
}

// Untupled4 converts a function with a [Tuple4] parameter into a function with 4 parameters
// The inverse function is [Tupled4]
func Untupled4[F ~func(Tuple4[T1, T2, T3, T4]) R, T1, T2, T3, T4, R any](f F) func(T1, T2, T3, T4) R {
	return func(t1 T1, t2 T2, t3 T3, t4 T4) R {
		return f(MakeTuple4(t1, t2, t3, t4))
	}
}

// Monoid4 creates a [Monoid] for a [Tuple4] based on 4 monoids for the contained types
func Monoid4[T1, T2, T3, T4 any](m1 M.Monoid[T1], m2 M.Monoid[T2], m3 M.Monoid[T3], m4 M.Monoid[T4]) M.Monoid[Tuple4[T1, T2, T3, T4]] {
	return M.MakeMonoid(func(l, r Tuple4[T1, T2, T3, T4]) Tuple4[T1, T2, T3, T4] {
		return MakeTuple4(m1.Concat(l.F1, r.F1), m2.Concat(l.F2, r.F2), m3.Concat(l.F3, r.F3), m4.Concat(l.F4, r.F4))
	}, MakeTuple4(m1.Empty(), m2.Empty(), m3.Empty(), m4.Empty()))
}

// Ord4 creates n [Ord] for a [Tuple4] based on 4 [Ord]s for the contained types
func Ord4[T1, T2, T3, T4 any](o1 O.Ord[T1], o2 O.Ord[T2], o3 O.Ord[T3], o4 O.Ord[T4]) O.Ord[Tuple4[T1, T2, T3, T4]] {
	return O.MakeOrd(func(l, r Tuple4[T1, T2, T3, T4]) int {
		if c := o1.Compare(l.F1, r.F1); c != 0 {
			return c
		}
		if c := o2.Compare(l.F2, r.F2); c != 0 {
			return c
		}
		if c := o3.Compare(l.F3, r.F3); c != 0 {
			return c
		}
		if c := o4.Compare(l.F4, r.F4); c != 0 {
			return c
		}
		return 0
	}, func(l, r Tuple4[T1, T2, T3, T4]) bool {
		return o1.Equals(l.F1, r.F1) && o2.Equals(l.F2, r.F2) && o3.Equals(l.F3, r.F3) && o4.Equals(l.F4, r.F4)
	})
}

// Map4 maps each value of a [Tuple4] via a mapping function
func Map4[F1 ~func(T1) R1, F2 ~func(T2) R2, F3 ~func(T3) R3, F4 ~func(T4) R4, T1, R1, T2, R2, T3, R3, T4, R4 any](f1 F1, f2 F2, f3 F3, f4 F4) func(Tuple4[T1, T2, T3, T4]) Tuple4[R1, R2, R3, R4] {
	return func(t Tuple4[T1, T2, T3, T4]) Tuple4[R1, R2, R3, R4] {
		return MakeTuple4(
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
		)
	}
}

// Replicate4 creates a [Tuple4] with all fields set to the input value `t`
func Replicate4[T any](t T) Tuple4[T, T, T, T] {
	return MakeTuple4(t, t, t, t)
}

// String prints some debug info for the [Tuple4]
func (t Tuple4[T1, T2, T3, T4]) String() string {
	return tupleString(t.F1, t.F2, t.F3, t.F4)
}

// MarshalJSON marshals the [Tuple4] into a JSON array
func (t Tuple4[T1, T2, T3, T4]) MarshalJSON() ([]byte, error) {
	return tupleMarshalJSON(t.F1, t.F2, t.F3, t.F4)
}

// UnmarshalJSON unmarshals a JSON array into a [Tuple4]
func (t *Tuple4[T1, T2, T3, T4]) UnmarshalJSON(data []byte) error {
	return tupleUnmarshalJSON(data, &t.F1, &t.F2, &t.F3, &t.F4)
}

// ToArray converts the [Tuple4] into an array of type [R] using 4 transformation functions from [T] to [R]
// The inverse function is [FromArray4]
func ToArray4[F1 ~func(T1) R, F2 ~func(T2) R, F3 ~func(T3) R, F4 ~func(T4) R, T1, T2, T3, T4, R any](f1 F1, f2 F2, f3 F3, f4 F4) func(t Tuple4[T1, T2, T3, T4]) []R {
	return func(t Tuple4[T1, T2, T3, T4]) []R {
		return []R{
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
		}
	}
}

// FromArray converts an array of [R] into a [Tuple4] using 4 functions from [R] to [T]
// The inverse function is [ToArray4]
func FromArray4[F1 ~func(R) T1, F2 ~func(R) T2, F3 ~func(R) T3, F4 ~func(R) T4, T1, T2, T3, T4, R any](f1 F1, f2 F2, f3 F3, f4 F4) func(r []R) Tuple4[T1, T2, T3, T4] {
	return func(r []R) Tuple4[T1, T2, T3, T4] {
		return MakeTuple4(
			f1(r[0]),
			f2(r[1]),
			f3(r[2]),
			f4(r[3]),
		)
	}
}

// Push4 creates a [Tuple5] from a [Tuple4] by appending a constant value
func Push4[T1, T2, T3, T4, T5 any](value T5) func(Tuple4[T1, T2, T3, T4]) Tuple5[T1, T2, T3, T4, T5] {
	return func(t Tuple4[T1, T2, T3, T4]) Tuple5[T1, T2, T3, T4, T5] {
		return MakeTuple5(t.F1, t.F2, t.F3, t.F4, value)
	}
}

// MakeTuple5 is a function that converts its 5 parameters into a [Tuple5]
func MakeTuple5[T1, T2, T3, T4, T5 any](t1 T1, t2 T2, t3 T3, t4 T4, t5 T5) Tuple5[T1, T2, T3, T4, T5] {
	return Tuple5[T1, T2, T3, T4, T5]{t1, t2, t3, t4, t5}
}

// Tupled5 converts a function with 5 parameters into a function taking a Tuple5
// The inverse function is [Untupled5]
func Tupled5[F ~func(T1, T2, T3, T4, T5) R, T1, T2, T3, T4, T5, R any](f F) func(Tuple5[T1, T2, T3, T4, T5]) R {
	return func(t Tuple5[T1, T2, T3, T4, T5]) R {
		return f(t.F1, t.F2, t.F3, t.F4, t.F5)
	}
}

// Untupled5 converts a function with a [Tuple5] parameter into a function with 5 parameters
// The inverse function is [Tupled5]
func Untupled5[F ~func(Tuple5[T1, T2, T3, T4, T5]) R, T1, T2, T3, T4, T5, R any](f F) func(T1, T2, T3, T4, T5) R {
	return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5) R {
		return f(MakeTuple5(t1, t2, t3, t4, t5))
	}
}

// Monoid5 creates a [Monoid] for a [Tuple5] based on 5 monoids for the contained types
func Monoid5[T1, T2, T3, T4, T5 any](m1 M.Monoid[T1], m2 M.Monoid[T2], m3 M.Monoid[T3], m4 M.Monoid[T4], m5 M.Monoid[T5]) M.Monoid[Tuple5[T1, T2, T3, T4, T5]] {
	return M.MakeMonoid(func(l, r Tuple5[T1, T2, T3, T4, T5]) Tuple5[T1, T2, T3, T4, T5] {
		return MakeTuple5(m1.Concat(l.F1, r.F1), m2.Concat(l.F2, r.F2), m3.Concat(l.F3, r.F3), m4.Concat(l.F4, r.F4), m5.Concat(l.F5, r.F5))
	}, MakeTuple5(m1.Empty(), m2.Empty(), m3.Empty(), m4.Empty(), m5.Empty()))
}

// Ord5 creates n [Ord] for a [Tuple5] based on 5 [Ord]s for the contained types
func Ord5[T1, T2, T3, T4, T5 any](o1 O.Ord[T1], o2 O.Ord[T2], o3 O.Ord[T3], o4 O.Ord[T4], o5 O.Ord[T5]) O.Ord[Tuple5[T1, T2, T3, T4, T5]] {
	return O.MakeOrd(func(l, r Tuple5[T1, T2, T3, T4, T5]) int {
		if c := o1.Compare(l.F1, r.F1); c != 0 {
			return c
		}
		if c := o2.Compare(l.F2, r.F2); c != 0 {
			return c
		}
		if c := o3.Compare(l.F3, r.F3); c != 0 {
			return c
		}
		if c := o4.Compare(l.F4, r.F4); c != 0 {
			return c
		}
		if c := o5.Compare(l.F5, r.F5); c != 0 {
			return c
		}
		return 0
	}, func(l, r Tuple5[T1, T2, T3, T4, T5]) bool {
		return o1.Equals(l.F1, r.F1) && o2.Equals(l.F2, r.F2) && o3.Equals(l.F3, r.F3) && o4.Equals(l.F4, r.F4) && o5.Equals(l.F5, r.F5)
	})
}

// Map5 maps each value of a [Tuple5] via a mapping function
func Map5[F1 ~func(T1) R1, F2 ~func(T2) R2, F3 ~func(T3) R3, F4 ~func(T4) R4, F5 ~func(T5) R5, T1, R1, T2, R2, T3, R3, T4, R4, T5, R5 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) func(Tuple5[T1, T2, T3, T4, T5]) Tuple5[R1, R2, R3, R4, R5] {
	return func(t Tuple5[T1, T2, T3, T4, T5]) Tuple5[R1, R2, R3, R4, R5] {
		return MakeTuple5(
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
			f5(t.F5),
		)
	}
}

// Replicate5 creates a [Tuple5] with all fields set to the input value `t`
func Replicate5[T any](t T) Tuple5[T, T, T, T, T] {
	return MakeTuple5(t, t, t, t, t)
}

// String prints some debug info for the [Tuple5]
func (t Tuple5[T1, T2, T3, T4, T5]) String() string {
	return tupleString(t.F1, t.F2, t.F3, t.F4, t.F5)
}

// MarshalJSON marshals the [Tuple5] into a JSON array
func (t Tuple5[T1, T2, T3, T4, T5]) MarshalJSON() ([]byte, error) {
	return tupleMarshalJSON(t.F1, t.F2, t.F3, t.F4, t.F5)
}

// UnmarshalJSON unmarshals a JSON array into a [Tuple5]
func (t *Tuple5[T1, T2, T3, T4, T5]) UnmarshalJSON(data []byte) error {
	return tupleUnmarshalJSON(data, &t.F1, &t.F2, &t.F3, &t.F4, &t.F5)
}

// ToArray converts the [Tuple5] into an array of type [R] using 5 transformation functions from [T] to [R]
// The inverse function is [FromArray5]
func ToArray5[F1 ~func(T1) R, F2 ~func(T2) R, F3 ~func(T3) R, F4 ~func(T4) R, F5 ~func(T5) R, T1, T2, T3, T4, T5, R any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) func(t Tuple5[T1, T2, T3, T4, T5]) []R {
	return func(t Tuple5[T1, T2, T3, T4, T5]) []R {
		return []R{
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
			f5(t.F5),
		}
	}
}

// FromArray converts an array of [R] into a [Tuple5] using 5 functions from [R] to [T]
// The inverse function is [ToArray5]
func FromArray5[F1 ~func(R) T1, F2 ~func(R) T2, F3 ~func(R) T3, F4 ~func(R) T4, F5 ~func(R) T5, T1, T2, T3, T4, T5, R any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) func(r []R) Tuple5[T1, T2, T3, T4, T5] {
	return func(r []R) Tuple5[T1, T2, T3, T4, T5] {
		return MakeTuple5(
			f1(r[0]),
			f2(r[1]),
			f3(r[2]),
			f4(r[3]),
			f5(r[4]),
		)
	}
}

// Push5 creates a [Tuple6] from a [Tuple5] by appending a constant value
func Push5[T1, T2, T3, T4, T5, T6 any](value T6) func(Tuple5[T1, T2, T3, T4, T5]) Tuple6[T1, T2, T3, T4, T5, T6] {
	return func(t Tuple5[T1, T2, T3, T4, T5]) Tuple6[T1, T2, T3, T4, T5, T6] {
		return MakeTuple6(t.F1, t.F2, t.F3, t.F4, t.F5, value)
	}
}

// MakeTuple6 is a function that converts its 6 parameters into a [Tuple6]
func MakeTuple6[T1, T2, T3, T4, T5, T6 any](t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6) Tuple6[T1, T2, T3, T4, T5, T6] {
	return Tuple6[T1, T2, T3, T4, T5, T6]{t1, t2, t3, t4, t5, t6}
}

// Tupled6 converts a function with 6 parameters into a function taking a Tuple6
// The inverse function is [Untupled6]
func Tupled6[F ~func(T1, T2, T3, T4, T5, T6) R, T1, T2, T3, T4, T5, T6, R any](f F) func(Tuple6[T1, T2, T3, T4, T5, T6]) R {
	return func(t Tuple6[T1, T2, T3, T4, T5, T6]) R {
		return f(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6)
	}
}

// Untupled6 converts a function with a [Tuple6] parameter into a function with 6 parameters
// The inverse function is [Tupled6]
func Untupled6[F ~func(Tuple6[T1, T2, T3, T4, T5, T6]) R, T1, T2, T3, T4, T5, T6, R any](f F) func(T1, T2, T3, T4, T5, T6) R {
	return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6) R {
		return f(MakeTuple6(t1, t2, t3, t4, t5, t6))
	}
}

// Monoid6 creates a [Monoid] for a [Tuple6] based on 6 monoids for the contained types
func Monoid6[T1, T2, T3, T4, T5, T6 any](m1 M.Monoid[T1], m2 M.Monoid[T2], m3 M.Monoid[T3], m4 M.Monoid[T4], m5 M.Monoid[T5], m6 M.Monoid[T6]) M.Monoid[Tuple6[T1, T2, T3, T4, T5, T6]] {
	return M.MakeMonoid(func(l, r Tuple6[T1, T2, T3, T4, T5, T6]) Tuple6[T1, T2, T3, T4, T5, T6] {
		return MakeTuple6(m1.Concat(l.F1, r.F1), m2.Concat(l.F2, r.F2), m3.Concat(l.F3, r.F3), m4.Concat(l.F4, r.F4), m5.Concat(l.F5, r.F5), m6.Concat(l.F6, r.F6))
	}, MakeTuple6(m1.Empty(), m2.Empty(), m3.Empty(), m4.Empty(), m5.Empty(), m6.Empty()))
}

// Ord6 creates n [Ord] for a [Tuple6] based on 6 [Ord]s for the contained types
func Ord6[T1, T2, T3, T4, T5, T6 any](o1 O.Ord[T1], o2 O.Ord[T2], o3 O.Ord[T3], o4 O.Ord[T4], o5 O.Ord[T5], o6 O.Ord[T6]) O.Ord[Tuple6[T1, T2, T3, T4, T5, T6]] {
	return O.MakeOrd(func(l, r Tuple6[T1, T2, T3, T4, T5, T6]) int {
		if c := o1.Compare(l.F1, r.F1); c != 0 {
			return c
		}
		if c := o2.Compare(l.F2, r.F2); c != 0 {
			return c
		}
		if c := o3.Compare(l.F3, r.F3); c != 0 {
			return c
		}
		if c := o4.Compare(l.F4, r.F4); c != 0 {
			return c
		}
		if c := o5.Compare(l.F5, r.F5); c != 0 {
			return c
		}
		if c := o6.Compare(l.F6, r.F6); c != 0 {
			return c
		}
		return 0
	}, func(l, r Tuple6[T1, T2, T3, T4, T5, T6]) bool {
		return o1.Equals(l.F1, r.F1) && o2.Equals(l.F2, r.F2) && o3.Equals(l.F3, r.F3) && o4.Equals(l.F4, r.F4) && o5.Equals(l.F5, r.F5) && o6.Equals(l.F6, r.F6)
	})
}

// Map6 maps each value of a [Tuple6] via a mapping function
func Map6[F1 ~func(T1) R1, F2 ~func(T2) R2, F3 ~func(T3) R3, F4 ~func(T4) R4, F5 ~func(T5) R5, F6 ~func(T6) R6, T1, R1, T2, R2, T3, R3, T4, R4, T5, R5, T6, R6 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) func(Tuple6[T1, T2, T3, T4, T5, T6]) Tuple6[R1, R2, R3, R4, R5, R6] {
	return func(t Tuple6[T1, T2, T3, T4, T5, T6]) Tuple6[R1, R2, R3, R4, R5, R6] {
		return MakeTuple6(
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
			f5(t.F5),
			f6(t.F6),
		)
	}
}

// Replicate6 creates a [Tuple6] with all fields set to the input value `t`
func Replicate6[T any](t T) Tuple6[T, T, T, T, T, T] {
	return MakeTuple6(t, t, t, t, t, t)
}

// String prints some debug info for the [Tuple6]
func (t Tuple6[T1, T2, T3, T4, T5, T6]) String() string {
	return tupleString(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6)
}

// MarshalJSON marshals the [Tuple6] into a JSON array
func (t Tuple6[T1, T2, T3, T4, T5, T6]) MarshalJSON() ([]byte, error) {
	return tupleMarshalJSON(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6)
}

// UnmarshalJSON unmarshals a JSON array into a [Tuple6]
func (t *Tuple6[T1, T2, T3, T4, T5, T6]) UnmarshalJSON(data []byte) error {
	return tupleUnmarshalJSON(data, &t.F1, &t.F2, &t.F3, &t.F4, &t.F5, &t.F6)
}

// ToArray converts the [Tuple6] into an array of type [R] using 6 transformation functions from [T] to [R]
// The inverse function is [FromArray6]
func ToArray6[F1 ~func(T1) R, F2 ~func(T2) R, F3 ~func(T3) R, F4 ~func(T4) R, F5 ~func(T5) R, F6 ~func(T6) R, T1, T2, T3, T4, T5, T6, R any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) func(t Tuple6[T1, T2, T3, T4, T5, T6]) []R {
	return func(t Tuple6[T1, T2, T3, T4, T5, T6]) []R {
		return []R{
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
			f5(t.F5),
			f6(t.F6),
		}
	}
}

// FromArray converts an array of [R] into a [Tuple6] using 6 functions from [R] to [T]
// The inverse function is [ToArray6]
func FromArray6[F1 ~func(R) T1, F2 ~func(R) T2, F3 ~func(R) T3, F4 ~func(R) T4, F5 ~func(R) T5, F6 ~func(R) T6, T1, T2, T3, T4, T5, T6, R any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) func(r []R) Tuple6[T1, T2, T3, T4, T5, T6] {
	return func(r []R) Tuple6[T1, T2, T3, T4, T5, T6] {
		return MakeTuple6(
			f1(r[0]),
			f2(r[1]),
			f3(r[2]),
			f4(r[3]),
			f5(r[4]),
			f6(r[5]),
		)
	}
}

// Push6 creates a [Tuple7] from a [Tuple6] by appending a constant value
func Push6[T1, T2, T3, T4, T5, T6, T7 any](value T7) func(Tuple6[T1, T2, T3, T4, T5, T6]) Tuple7[T1, T2, T3, T4, T5, T6, T7] {
	return func(t Tuple6[T1, T2, T3, T4, T5, T6]) Tuple7[T1, T2, T3, T4, T5, T6, T7] {
		return MakeTuple7(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, value)
	}
}

// MakeTuple7 is a function that converts its 7 parameters into a [Tuple7]
func MakeTuple7[T1, T2, T3, T4, T5, T6, T7 any](t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7) Tuple7[T1, T2, T3, T4, T5, T6, T7] {
	return Tuple7[T1, T2, T3, T4, T5, T6, T7]{t1, t2, t3, t4, t5, t6, t7}
}

// Tupled7 converts a function with 7 parameters into a function taking a Tuple7
// The inverse function is [Untupled7]
func Tupled7[F ~func(T1, T2, T3, T4, T5, T6, T7) R, T1, T2, T3, T4, T5, T6, T7, R any](f F) func(Tuple7[T1, T2, T3, T4, T5, T6, T7]) R {
	return func(t Tuple7[T1, T2, T3, T4, T5, T6, T7]) R {
		return f(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7)
	}
}

// Untupled7 converts a function with a [Tuple7] parameter into a function with 7 parameters
// The inverse function is [Tupled7]
func Untupled7[F ~func(Tuple7[T1, T2, T3, T4, T5, T6, T7]) R, T1, T2, T3, T4, T5, T6, T7, R any](f F) func(T1, T2, T3, T4, T5, T6, T7) R {
	return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7) R {
		return f(MakeTuple7(t1, t2, t3, t4, t5, t6, t7))
	}
}

// Monoid7 creates a [Monoid] for a [Tuple7] based on 7 monoids for the contained types
func Monoid7[T1, T2, T3, T4, T5, T6, T7 any](m1 M.Monoid[T1], m2 M.Monoid[T2], m3 M.Monoid[T3], m4 M.Monoid[T4], m5 M.Monoid[T5], m6 M.Monoid[T6], m7 M.Monoid[T7]) M.Monoid[Tuple7[T1, T2, T3, T4, T5, T6, T7]] {
	return M.MakeMonoid(func(l, r Tuple7[T1, T2, T3, T4, T5, T6, T7]) Tuple7[T1, T2, T3, T4, T5, T6, T7] {
		return MakeTuple7(m1.Concat(l.F1, r.F1), m2.Concat(l.F2, r.F2), m3.Concat(l.F3, r.F3), m4.Concat(l.F4, r.F4), m5.Concat(l.F5, r.F5), m6.Concat(l.F6, r.F6), m7.Concat(l.F7, r.F7))
	}, MakeTuple7(m1.Empty(), m2.Empty(), m3.Empty(), m4.Empty(), m5.Empty(), m6.Empty(), m7.Empty()))
}

// Ord7 creates n [Ord] for a [Tuple7] based on 7 [Ord]s for the contained types
func Ord7[T1, T2, T3, T4, T5, T6, T7 any](o1 O.Ord[T1], o2 O.Ord[T2], o3 O.Ord[T3], o4 O.Ord[T4], o5 O.Ord[T5], o6 O.Ord[T6], o7 O.Ord[T7]) O.Ord[Tuple7[T1, T2, T3, T4, T5, T6, T7]] {
	return O.MakeOrd(func(l, r Tuple7[T1, T2, T3, T4, T5, T6, T7]) int {
		if c := o1.Compare(l.F1, r.F1); c != 0 {
			return c
		}
		if c := o2.Compare(l.F2, r.F2); c != 0 {
			return c
		}
		if c := o3.Compare(l.F3, r.F3); c != 0 {
			return c
		}
		if c := o4.Compare(l.F4, r.F4); c != 0 {
			return c
		}
		if c := o5.Compare(l.F5, r.F5); c != 0 {
			return c
		}
		if c := o6.Compare(l.F6, r.F6); c != 0 {
			return c
		}
		if c := o7.Compare(l.F7, r.F7); c != 0 {
			return c
		}
		return 0
	}, func(l, r Tuple7[T1, T2, T3, T4, T5, T6, T7]) bool {
		return o1.Equals(l.F1, r.F1) && o2.Equals(l.F2, r.F2) && o3.Equals(l.F3, r.F3) && o4.Equals(l.F4, r.F4) && o5.Equals(l.F5, r.F5) && o6.Equals(l.F6, r.F6) && o7.Equals(l.F7, r.F7)
	})
}

// Map7 maps each value of a [Tuple7] via a mapping function
func Map7[F1 ~func(T1) R1, F2 ~func(T2) R2, F3 ~func(T3) R3, F4 ~func(T4) R4, F5 ~func(T5) R5, F6 ~func(T6) R6, F7 ~func(T7) R7, T1, R1, T2, R2, T3, R3, T4, R4, T5, R5, T6, R6, T7, R7 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) func(Tuple7[T1, T2, T3, T4, T5, T6, T7]) Tuple7[R1, R2, R3, R4, R5, R6, R7] {
	return func(t Tuple7[T1, T2, T3, T4, T5, T6, T7]) Tuple7[R1, R2, R3, R4, R5, R6, R7] {
		return MakeTuple7(
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
			f5(t.F5),
			f6(t.F6),
			f7(t.F7),
		)
	}
}

// Replicate7 creates a [Tuple7] with all fields set to the input value `t`
func Replicate7[T any](t T) Tuple7[T, T, T, T, T, T, T] {
	return MakeTuple7(t, t, t, t, t, t, t)
}

// String prints some debug info for the [Tuple7]
func (t Tuple7[T1, T2, T3, T4, T5, T6, T7]) String() string {
	return tupleString(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7)
}

// MarshalJSON marshals the [Tuple7] into a JSON array
func (t Tuple7[T1, T2, T3, T4, T5, T6, T7]) MarshalJSON() ([]byte, error) {
	return tupleMarshalJSON(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7)
}

// UnmarshalJSON unmarshals a JSON array into a [Tuple7]
func (t *Tuple7[T1, T2, T3, T4, T5, T6, T7]) UnmarshalJSON(data []byte) error {
	return tupleUnmarshalJSON(data, &t.F1, &t.F2, &t.F3, &t.F4, &t.F5, &t.F6, &t.F7)
}

// ToArray converts the [Tuple7] into an array of type [R] using 7 transformation functions from [T] to [R]
// The inverse function is [FromArray7]
func ToArray7[F1 ~func(T1) R, F2 ~func(T2) R, F3 ~func(T3) R, F4 ~func(T4) R, F5 ~func(T5) R, F6 ~func(T6) R, F7 ~func(T7) R, T1, T2, T3, T4, T5, T6, T7, R any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) func(t Tuple7[T1, T2, T3, T4, T5, T6, T7]) []R {
	return func(t Tuple7[T1, T2, T3, T4, T5, T6, T7]) []R {
		return []R{
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
			f5(t.F5),
			f6(t.F6),
			f7(t.F7),
		}
	}
}

// FromArray converts an array of [R] into a [Tuple7] using 7 functions from [R] to [T]
// The inverse function is [ToArray7]
func FromArray7[F1 ~func(R) T1, F2 ~func(R) T2, F3 ~func(R) T3, F4 ~func(R) T4, F5 ~func(R) T5, F6 ~func(R) T6, F7 ~func(R) T7, T1, T2, T3, T4, T5, T6, T7, R any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) func(r []R) Tuple7[T1, T2, T3, T4, T5, T6, T7] {
	return func(r []R) Tuple7[T1, T2, T3, T4, T5, T6, T7] {
		return MakeTuple7(
			f1(r[0]),
			f2(r[1]),
			f3(r[2]),
			f4(r[3]),
			f5(r[4]),
			f6(r[5]),
			f7(r[6]),
		)
	}
}

// Push7 creates a [Tuple8] from a [Tuple7] by appending a constant value
func Push7[T1, T2, T3, T4, T5, T6, T7, T8 any](value T8) func(Tuple7[T1, T2, T3, T4, T5, T6, T7]) Tuple8[T1, T2, T3, T4, T5, T6, T7, T8] {
	return func(t Tuple7[T1, T2, T3, T4, T5, T6, T7]) Tuple8[T1, T2, T3, T4, T5, T6, T7, T8] {
		return MakeTuple8(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, value)
	}
}

// MakeTuple8 is a function that converts its 8 parameters into a [Tuple8]
func MakeTuple8[T1, T2, T3, T4, T5, T6, T7, T8 any](t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8) Tuple8[T1, T2, T3, T4, T5, T6, T7, T8] {
	return Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]{t1, t2, t3, t4, t5, t6, t7, t8}
}

// Tupled8 converts a function with 8 parameters into a function taking a Tuple8
// The inverse function is [Untupled8]
func Tupled8[F ~func(T1, T2, T3, T4, T5, T6, T7, T8) R, T1, T2, T3, T4, T5, T6, T7, T8, R any](f F) func(Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]) R {
	return func(t Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]) R {
		return f(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8)
	}
}

// Untupled8 converts a function with a [Tuple8] parameter into a function with 8 parameters
// The inverse function is [Tupled8]
func Untupled8[F ~func(Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]) R, T1, T2, T3, T4, T5, T6, T7, T8, R any](f F) func(T1, T2, T3, T4, T5, T6, T7, T8) R {
	return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8) R {
		return f(MakeTuple8(t1, t2, t3, t4, t5, t6, t7, t8))
	}
}

// Monoid8 creates a [Monoid] for a [Tuple8] based on 8 monoids for the contained types
func Monoid8[T1, T2, T3, T4, T5, T6, T7, T8 any](m1 M.Monoid[T1], m2 M.Monoid[T2], m3 M.Monoid[T3], m4 M.Monoid[T4], m5 M.Monoid[T5], m6 M.Monoid[T6], m7 M.Monoid[T7], m8 M.Monoid[T8]) M.Monoid[Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]] {
	return M.MakeMonoid(func(l, r Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]) Tuple8[T1, T2, T3, T4, T5, T6, T7, T8] {
		return MakeTuple8(m1.Concat(l.F1, r.F1), m2.Concat(l.F2, r.F2), m3.Concat(l.F3, r.F3), m4.Concat(l.F4, r.F4), m5.Concat(l.F5, r.F5), m6.Concat(l.F6, r.F6), m7.Concat(l.F7, r.F7), m8.Concat(l.F8, r.F8))
	}, MakeTuple8(m1.Empty(), m2.Empty(), m3.Empty(), m4.Empty(), m5.Empty(), m6.Empty(), m7.Empty(), m8.Empty()))
}

// Ord8 creates n [Ord] for a [Tuple8] based on 8 [Ord]s for the contained types
func Ord8[T1, T2, T3, T4, T5, T6, T7, T8 any](o1 O.Ord[T1], o2 O.Ord[T2], o3 O.Ord[T3], o4 O.Ord[T4], o5 O.Ord[T5], o6 O.Ord[T6], o7 O.Ord[T7], o8 O.Ord[T8]) O.Ord[Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]] {
	return O.MakeOrd(func(l, r Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]) int {
		if c := o1.Compare(l.F1, r.F1); c != 0 {
			return c
		}
		if c := o2.Compare(l.F2, r.F2); c != 0 {
			return c
		}
		if c := o3.Compare(l.F3, r.F3); c != 0 {
			return c
		}
		if c := o4.Compare(l.F4, r.F4); c != 0 {
			return c
		}
		if c := o5.Compare(l.F5, r.F5); c != 0 {
			return c
		}
		if c := o6.Compare(l.F6, r.F6); c != 0 {
			return c
		}
		if c := o7.Compare(l.F7, r.F7); c != 0 {
			return c
		}
		if c := o8.Compare(l.F8, r.F8); c != 0 {
			return c
		}
		return 0
	}, func(l, r Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]) bool {
		return o1.Equals(l.F1, r.F1) && o2.Equals(l.F2, r.F2) && o3.Equals(l.F3, r.F3) && o4.Equals(l.F4, r.F4) && o5.Equals(l.F5, r.F5) && o6.Equals(l.F6, r.F6) && o7.Equals(l.F7, r.F7) && o8.Equals(l.F8, r.F8)
	})
}

// Map8 maps each value of a [Tuple8] via a mapping function
func Map8[F1 ~func(T1) R1, F2 ~func(T2) R2, F3 ~func(T3) R3, F4 ~func(T4) R4, F5 ~func(T5) R5, F6 ~func(T6) R6, F7 ~func(T7) R7, F8 ~func(T8) R8, T1, R1, T2, R2, T3, R3, T4, R4, T5, R5, T6, R6, T7, R7, T8, R8 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) func(Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]) Tuple8[R1, R2, R3, R4, R5, R6, R7, R8] {
	return func(t Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]) Tuple8[R1, R2, R3, R4, R5, R6, R7, R8] {
		return MakeTuple8(
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
			f5(t.F5),
			f6(t.F6),
			f7(t.F7),
			f8(t.F8),
		)
	}
}

// Replicate8 creates a [Tuple8] with all fields set to the input value `t`
func Replicate8[T any](t T) Tuple8[T, T, T, T, T, T, T, T] {
	return MakeTuple8(t, t, t, t, t, t, t, t)
}

// String prints some debug info for the [Tuple8]
func (t Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]) String() string {
	return tupleString(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8)
}

// MarshalJSON marshals the [Tuple8] into a JSON array
func (t Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]) MarshalJSON() ([]byte, error) {
	return tupleMarshalJSON(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8)
}

// UnmarshalJSON unmarshals a JSON array into a [Tuple8]
func (t *Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]) UnmarshalJSON(data []byte) error {
	return tupleUnmarshalJSON(data, &t.F1, &t.F2, &t.F3, &t.F4, &t.F5, &t.F6, &t.F7, &t.F8)
}

// ToArray converts the [Tuple8] into an array of type [R] using 8 transformation functions from [T] to [R]
// The inverse function is [FromArray8]
func ToArray8[F1 ~func(T1) R, F2 ~func(T2) R, F3 ~func(T3) R, F4 ~func(T4) R, F5 ~func(T5) R, F6 ~func(T6) R, F7 ~func(T7) R, F8 ~func(T8) R, T1, T2, T3, T4, T5, T6, T7, T8, R any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) func(t Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]) []R {
	return func(t Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]) []R {
		return []R{
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
			f5(t.F5),
			f6(t.F6),
			f7(t.F7),
			f8(t.F8),
		}
	}
}

// FromArray converts an array of [R] into a [Tuple8] using 8 functions from [R] to [T]
// The inverse function is [ToArray8]
func FromArray8[F1 ~func(R) T1, F2 ~func(R) T2, F3 ~func(R) T3, F4 ~func(R) T4, F5 ~func(R) T5, F6 ~func(R) T6, F7 ~func(R) T7, F8 ~func(R) T8, T1, T2, T3, T4, T5, T6, T7, T8, R any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) func(r []R) Tuple8[T1, T2, T3, T4, T5, T6, T7, T8] {
	return func(r []R) Tuple8[T1, T2, T3, T4, T5, T6, T7, T8] {
		return MakeTuple8(
			f1(r[0]),
			f2(r[1]),
			f3(r[2]),
			f4(r[3]),
			f5(r[4]),
			f6(r[5]),
			f7(r[6]),
			f8(r[7]),
		)
	}
}

// Push8 creates a [Tuple9] from a [Tuple8] by appending a constant value
func Push8[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](value T9) func(Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]) Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9] {
	return func(t Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]) Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9] {
		return MakeTuple9(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, value)
	}
}

// MakeTuple9 is a function that converts its 9 parameters into a [Tuple9]
func MakeTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9) Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9] {
	return Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]{t1, t2, t3, t4, t5, t6, t7, t8, t9}
}

// Tupled9 converts a function with 9 parameters into a function taking a Tuple9
// The inverse function is [Untupled9]
func Tupled9[F ~func(T1, T2, T3, T4, T5, T6, T7, T8, T9) R, T1, T2, T3, T4, T5, T6, T7, T8, T9, R any](f F) func(Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) R {
	return func(t Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) R {
		return f(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9)
	}
}

// Untupled9 converts a function with a [Tuple9] parameter into a function with 9 parameters
// The inverse function is [Tupled9]
func Untupled9[F ~func(Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) R, T1, T2, T3, T4, T5, T6, T7, T8, T9, R any](f F) func(T1, T2, T3, T4, T5, T6, T7, T8, T9) R {
	return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9) R {
		return f(MakeTuple9(t1, t2, t3, t4, t5, t6, t7, t8, t9))
	}
}

// Monoid9 creates a [Monoid] for a [Tuple9] based on 9 monoids for the contained types
func Monoid9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](m1 M.Monoid[T1], m2 M.Monoid[T2], m3 M.Monoid[T3], m4 M.Monoid[T4], m5 M.Monoid[T5], m6 M.Monoid[T6], m7 M.Monoid[T7], m8 M.Monoid[T8], m9 M.Monoid[T9]) M.Monoid[Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]] {
	return M.MakeMonoid(func(l, r Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9] {
		return MakeTuple9(m1.Concat(l.F1, r.F1), m2.Concat(l.F2, r.F2), m3.Concat(l.F3, r.F3), m4.Concat(l.F4, r.F4), m5.Concat(l.F5, r.F5), m6.Concat(l.F6, r.F6), m7.Concat(l.F7, r.F7), m8.Concat(l.F8, r.F8), m9.Concat(l.F9, r.F9))
	}, MakeTuple9(m1.Empty(), m2.Empty(), m3.Empty(), m4.Empty(), m5.Empty(), m6.Empty(), m7.Empty(), m8.Empty(), m9.Empty()))
}

// Ord9 creates n [Ord] for a [Tuple9] based on 9 [Ord]s for the contained types
func Ord9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](o1 O.Ord[T1], o2 O.Ord[T2], o3 O.Ord[T3], o4 O.Ord[T4], o5 O.Ord[T5], o6 O.Ord[T6], o7 O.Ord[T7], o8 O.Ord[T8], o9 O.Ord[T9]) O.Ord[Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]] {
	return O.MakeOrd(func(l, r Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) int {
		if c := o1.Compare(l.F1, r.F1); c != 0 {
			return c
		}
		if c := o2.Compare(l.F2, r.F2); c != 0 {
			return c
		}
		if c := o3.Compare(l.F3, r.F3); c != 0 {
			return c
		}
		if c := o4.Compare(l.F4, r.F4); c != 0 {
			return c
		}
		if c := o5.Compare(l.F5, r.F5); c != 0 {
			return c
		}
		if c := o6.Compare(l.F6, r.F6); c != 0 {
			return c
		}
		if c := o7.Compare(l.F7, r.F7); c != 0 {
			return c
		}
		if c := o8.Compare(l.F8, r.F8); c != 0 {
			return c
		}
		if c := o9.Compare(l.F9, r.F9); c != 0 {
			return c
		}
		return 0
	}, func(l, r Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) bool {
		return o1.Equals(l.F1, r.F1) && o2.Equals(l.F2, r.F2) && o3.Equals(l.F3, r.F3) && o4.Equals(l.F4, r.F4) && o5.Equals(l.F5, r.F5) && o6.Equals(l.F6, r.F6) && o7.Equals(l.F7, r.F7) && o8.Equals(l.F8, r.F8) && o9.Equals(l.F9, r.F9)
	})
}

// Map9 maps each value of a [Tuple9] via a mapping function
func Map9[F1 ~func(T1) R1, F2 ~func(T2) R2, F3 ~func(T3) R3, F4 ~func(T4) R4, F5 ~func(T5) R5, F6 ~func(T6) R6, F7 ~func(T7) R7, F8 ~func(T8) R8, F9 ~func(T9) R9, T1, R1, T2, R2, T3, R3, T4, R4, T5, R5, T6, R6, T7, R7, T8, R8, T9, R9 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) func(Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) Tuple9[R1, R2, R3, R4, R5, R6, R7, R8, R9] {
	return func(t Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) Tuple9[R1, R2, R3, R4, R5, R6, R7, R8, R9] {
		return MakeTuple9(
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
			f5(t.F5),
			f6(t.F6),
			f7(t.F7),
			f8(t.F8),
			f9(t.F9),
		)
	}
}

// Replicate9 creates a [Tuple9] with all fields set to the input value `t`
func Replicate9[T any](t T) Tuple9[T, T, T, T, T, T, T, T, T] {
	return MakeTuple9(t, t, t, t, t, t, t, t, t)
}

// String prints some debug info for the [Tuple9]
func (t Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) String() string {
	return tupleString(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9)
}

// MarshalJSON marshals the [Tuple9] into a JSON array
func (t Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) MarshalJSON() ([]byte, error) {
	return tupleMarshalJSON(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9)
}

// UnmarshalJSON unmarshals a JSON array into a [Tuple9]
func (t *Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) UnmarshalJSON(data []byte) error {
	return tupleUnmarshalJSON(data, &t.F1, &t.F2, &t.F3, &t.F4, &t.F5, &t.F6, &t.F7, &t.F8, &t.F9)
}

// ToArray converts the [Tuple9] into an array of type [R] using 9 transformation functions from [T] to [R]
// The inverse function is [FromArray9]
func ToArray9[F1 ~func(T1) R, F2 ~func(T2) R, F3 ~func(T3) R, F4 ~func(T4) R, F5 ~func(T5) R, F6 ~func(T6) R, F7 ~func(T7) R, F8 ~func(T8) R, F9 ~func(T9) R, T1, T2, T3, T4, T5, T6, T7, T8, T9, R any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) func(t Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) []R {
	return func(t Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) []R {
		return []R{
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
			f5(t.F5),
			f6(t.F6),
			f7(t.F7),
			f8(t.F8),
			f9(t.F9),
		}
	}
}

// FromArray converts an array of [R] into a [Tuple9] using 9 functions from [R] to [T]
// The inverse function is [ToArray9]
func FromArray9[F1 ~func(R) T1, F2 ~func(R) T2, F3 ~func(R) T3, F4 ~func(R) T4, F5 ~func(R) T5, F6 ~func(R) T6, F7 ~func(R) T7, F8 ~func(R) T8, F9 ~func(R) T9, T1, T2, T3, T4, T5, T6, T7, T8, T9, R any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) func(r []R) Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9] {
	return func(r []R) Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9] {
		return MakeTuple9(
			f1(r[0]),
			f2(r[1]),
			f3(r[2]),
			f4(r[3]),
			f5(r[4]),
			f6(r[5]),
			f7(r[6]),
			f8(r[7]),
			f9(r[8]),
		)
	}
}

// Push9 creates a [Tuple10] from a [Tuple9] by appending a constant value
func Push9[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](value T10) func(Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] {
	return func(t Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] {
		return MakeTuple10(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, value)
	}
}

// MakeTuple10 is a function that converts its 10 parameters into a [Tuple10]
func MakeTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10) Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] {
	return Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]{t1, t2, t3, t4, t5, t6, t7, t8, t9, t10}
}

// Tupled10 converts a function with 10 parameters into a function taking a Tuple10
// The inverse function is [Untupled10]
func Tupled10[F ~func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R any](f F) func(Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]) R {
	return func(t Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]) R {
		return f(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10)
	}
}

// Untupled10 converts a function with a [Tuple10] parameter into a function with 10 parameters
// The inverse function is [Tupled10]
func Untupled10[F ~func(Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]) R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R any](f F) func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) R {
	return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10) R {
		return f(MakeTuple10(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10))
	}
}

// Monoid10 creates a [Monoid] for a [Tuple10] based on 10 monoids for the contained types
func Monoid10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](m1 M.Monoid[T1], m2 M.Monoid[T2], m3 M.Monoid[T3], m4 M.Monoid[T4], m5 M.Monoid[T5], m6 M.Monoid[T6], m7 M.Monoid[T7], m8 M.Monoid[T8], m9 M.Monoid[T9], m10 M.Monoid[T10]) M.Monoid[Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]] {
	return M.MakeMonoid(func(l, r Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]) Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] {
		return MakeTuple10(m1.Concat(l.F1, r.F1), m2.Concat(l.F2, r.F2), m3.Concat(l.F3, r.F3), m4.Concat(l.F4, r.F4), m5.Concat(l.F5, r.F5), m6.Concat(l.F6, r.F6), m7.Concat(l.F7, r.F7), m8.Concat(l.F8, r.F8), m9.Concat(l.F9, r.F9), m10.Concat(l.F10, r.F10))
	}, MakeTuple10(m1.Empty(), m2.Empty(), m3.Empty(), m4.Empty(), m5.Empty(), m6.Empty(), m7.Empty(), m8.Empty(), m9.Empty(), m10.Empty()))
}

// Ord10 creates n [Ord] for a [Tuple10] based on 10 [Ord]s for the contained types
func Ord10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](o1 O.Ord[T1], o2 O.Ord[T2], o3 O.Ord[T3], o4 O.Ord[T4], o5 O.Ord[T5], o6 O.Ord[T6], o7 O.Ord[T7], o8 O.Ord[T8], o9 O.Ord[T9], o10 O.Ord[T10]) O.Ord[Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]] {
	return O.MakeOrd(func(l, r Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]) int {
		if c := o1.Compare(l.F1, r.F1); c != 0 {
			return c
		}
		if c := o2.Compare(l.F2, r.F2); c != 0 {
			return c
		}
		if c := o3.Compare(l.F3, r.F3); c != 0 {
			return c
		}
		if c := o4.Compare(l.F4, r.F4); c != 0 {
			return c
		}
		if c := o5.Compare(l.F5, r.F5); c != 0 {
			return c
		}
		if c := o6.Compare(l.F6, r.F6); c != 0 {
			return c
		}
		if c := o7.Compare(l.F7, r.F7); c != 0 {
			return c
		}
		if c := o8.Compare(l.F8, r.F8); c != 0 {
			return c
		}
		if c := o9.Compare(l.F9, r.F9); c != 0 {
			return c
		}
		if c := o10.Compare(l.F10, r.F10); c != 0 {
			return c
		}
		return 0
	}, func(l, r Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]) bool {
		return o1.Equals(l.F1, r.F1) && o2.Equals(l.F2, r.F2) && o3.Equals(l.F3, r.F3) && o4.Equals(l.F4, r.F4) && o5.Equals(l.F5, r.F5) && o6.Equals(l.F6, r.F6) && o7.Equals(l.F7, r.F7) && o8.Equals(l.F8, r.F8) && o9.Equals(l.F9, r.F9) && o10.Equals(l.F10, r.F10)
	})
}

// Map10 maps each value of a [Tuple10] via a mapping function
func Map10[F1 ~func(T1) R1, F2 ~func(T2) R2, F3 ~func(T3) R3, F4 ~func(T4) R4, F5 ~func(T5) R5, F6 ~func(T6) R6, F7 ~func(T7) R7, F8 ~func(T8) R8, F9 ~func(T9) R9, F10 ~func(T10) R10, T1, R1, T2, R2, T3, R3, T4, R4, T5, R5, T6, R6, T7, R7, T8, R8, T9, R9, T10, R10 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) func(Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]) Tuple10[R1, R2, R3, R4, R5, R6, R7, R8, R9, R10] {
	return func(t Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]) Tuple10[R1, R2, R3, R4, R5, R6, R7, R8, R9, R10] {
		return MakeTuple10(
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
			f5(t.F5),
			f6(t.F6),
			f7(t.F7),
			f8(t.F8),
			f9(t.F9),
			f10(t.F10),
		)
	}
}

// Replicate10 creates a [Tuple10] with all fields set to the input value `t`
func Replicate10[T any](t T) Tuple10[T, T, T, T, T, T, T, T, T, T] {
	return MakeTuple10(t, t, t, t, t, t, t, t, t, t)
}

// String prints some debug info for the [Tuple10]
func (t Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]) String() string {
	return tupleString(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10)
}

// MarshalJSON marshals the [Tuple10] into a JSON array
func (t Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]) MarshalJSON() ([]byte, error) {
	return tupleMarshalJSON(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10)
}

// UnmarshalJSON unmarshals a JSON array into a [Tuple10]
func (t *Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]) UnmarshalJSON(data []byte) error {
	return tupleUnmarshalJSON(data, &t.F1, &t.F2, &t.F3, &t.F4, &t.F5, &t.F6, &t.F7, &t.F8, &t.F9, &t.F10)
}

// ToArray converts the [Tuple10] into an array of type [R] using 10 transformation functions from [T] to [R]
// The inverse function is [FromArray10]
func ToArray10[F1 ~func(T1) R, F2 ~func(T2) R, F3 ~func(T3) R, F4 ~func(T4) R, F5 ~func(T5) R, F6 ~func(T6) R, F7 ~func(T7) R, F8 ~func(T8) R, F9 ~func(T9) R, F10 ~func(T10) R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) func(t Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]) []R {
	return func(t Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]) []R {
		return []R{
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
			f5(t.F5),
			f6(t.F6),
			f7(t.F7),
			f8(t.F8),
			f9(t.F9),
			f10(t.F10),
		}
	}
}

// FromArray converts an array of [R] into a [Tuple10] using 10 functions from [R] to [T]
// The inverse function is [ToArray10]
func FromArray10[F1 ~func(R) T1, F2 ~func(R) T2, F3 ~func(R) T3, F4 ~func(R) T4, F5 ~func(R) T5, F6 ~func(R) T6, F7 ~func(R) T7, F8 ~func(R) T8, F9 ~func(R) T9, F10 ~func(R) T10, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) func(r []R) Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] {
	return func(r []R) Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] {
		return MakeTuple10(
			f1(r[0]),
			f2(r[1]),
			f3(r[2]),
			f4(r[3]),
			f5(r[4]),
			f6(r[5]),
			f7(r[6]),
			f8(r[7]),
			f9(r[8]),
			f10(r[9]),
		)
	}
}

// Push10 creates a [Tuple11] from a [Tuple10] by appending a constant value
func Push10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 any](value T11) func(Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]) Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11] {
	return func(t Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]) Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11] {
		return MakeTuple11(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10, value)
	}
}

// MakeTuple11 is a function that converts its 11 parameters into a [Tuple11]
func MakeTuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 any](t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10, t11 T11) Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11] {
	return Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]{t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11}
}

// Tupled11 converts a function with 11 parameters into a function taking a Tuple11
// The inverse function is [Untupled11]
func Tupled11[F ~func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R any](f F) func(Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]) R {
	return func(t Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]) R {
		return f(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10, t.F11)
	}
}

// Untupled11 converts a function with a [Tuple11] parameter into a function with 11 parameters
// The inverse function is [Tupled11]
func Untupled11[F ~func(Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]) R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R any](f F) func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) R {
	return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10, t11 T11) R {
		return f(MakeTuple11(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11))
	}
}

// Monoid11 creates a [Monoid] for a [Tuple11] based on 11 monoids for the contained types
func Monoid11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 any](m1 M.Monoid[T1], m2 M.Monoid[T2], m3 M.Monoid[T3], m4 M.Monoid[T4], m5 M.Monoid[T5], m6 M.Monoid[T6], m7 M.Monoid[T7], m8 M.Monoid[T8], m9 M.Monoid[T9], m10 M.Monoid[T10], m11 M.Monoid[T11]) M.Monoid[Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]] {
	return M.MakeMonoid(func(l, r Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]) Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11] {
		return MakeTuple11(m1.Concat(l.F1, r.F1), m2.Concat(l.F2, r.F2), m3.Concat(l.F3, r.F3), m4.Concat(l.F4, r.F4), m5.Concat(l.F5, r.F5), m6.Concat(l.F6, r.F6), m7.Concat(l.F7, r.F7), m8.Concat(l.F8, r.F8), m9.Concat(l.F9, r.F9), m10.Concat(l.F10, r.F10), m11.Concat(l.F11, r.F11))
	}, MakeTuple11(m1.Empty(), m2.Empty(), m3.Empty(), m4.Empty(), m5.Empty(), m6.Empty(), m7.Empty(), m8.Empty(), m9.Empty(), m10.Empty(), m11.Empty()))
}

// Ord11 creates n [Ord] for a [Tuple11] based on 11 [Ord]s for the contained types
func Ord11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 any](o1 O.Ord[T1], o2 O.Ord[T2], o3 O.Ord[T3], o4 O.Ord[T4], o5 O.Ord[T5], o6 O.Ord[T6], o7 O.Ord[T7], o8 O.Ord[T8], o9 O.Ord[T9], o10 O.Ord[T10], o11 O.Ord[T11]) O.Ord[Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]] {
	return O.MakeOrd(func(l, r Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]) int {
		if c := o1.Compare(l.F1, r.F1); c != 0 {
			return c
		}
		if c := o2.Compare(l.F2, r.F2); c != 0 {
			return c
		}
		if c := o3.Compare(l.F3, r.F3); c != 0 {
			return c
		}
		if c := o4.Compare(l.F4, r.F4); c != 0 {
			return c
		}
		if c := o5.Compare(l.F5, r.F5); c != 0 {
			return c
		}
		if c := o6.Compare(l.F6, r.F6); c != 0 {
			return c
		}
		if c := o7.Compare(l.F7, r.F7); c != 0 {
			return c
		}
		if c := o8.Compare(l.F8, r.F8); c != 0 {
			return c
		}
		if c := o9.Compare(l.F9, r.F9); c != 0 {
			return c
		}
		if c := o10.Compare(l.F10, r.F10); c != 0 {
			return c
		}
		if c := o11.Compare(l.F11, r.F11); c != 0 {
			return c
		}
		return 0
	}, func(l, r Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]) bool {
		return o1.Equals(l.F1, r.F1) && o2.Equals(l.F2, r.F2) && o3.Equals(l.F3, r.F3) && o4.Equals(l.F4, r.F4) && o5.Equals(l.F5, r.F5) && o6.Equals(l.F6, r.F6) && o7.Equals(l.F7, r.F7) && o8.Equals(l.F8, r.F8) && o9.Equals(l.F9, r.F9) && o10.Equals(l.F10, r.F10) && o11.Equals(l.F11, r.F11)
	})
}

// Map11 maps each value of a [Tuple11] via a mapping function
func Map11[F1 ~func(T1) R1, F2 ~func(T2) R2, F3 ~func(T3) R3, F4 ~func(T4) R4, F5 ~func(T5) R5, F6 ~func(T6) R6, F7 ~func(T7) R7, F8 ~func(T8) R8, F9 ~func(T9) R9, F10 ~func(T10) R10, F11 ~func(T11) R11, T1, R1, T2, R2, T3, R3, T4, R4, T5, R5, T6, R6, T7, R7, T8, R8, T9, R9, T10, R10, T11, R11 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11) func(Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]) Tuple11[R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11] {
	return func(t Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]) Tuple11[R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11] {
		return MakeTuple11(
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
			f5(t.F5),
			f6(t.F6),
			f7(t.F7),
			f8(t.F8),
			f9(t.F9),
			f10(t.F10),
			f11(t.F11),
		)
	}
}

// Replicate11 creates a [Tuple11] with all fields set to the input value `t`
func Replicate11[T any](t T) Tuple11[T, T, T, T, T, T, T, T, T, T, T] {
	return MakeTuple11(t, t, t, t, t, t, t, t, t, t, t)
}

// String prints some debug info for the [Tuple11]
func (t Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]) String() string {
	return tupleString(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10, t.F11)
}

// MarshalJSON marshals the [Tuple11] into a JSON array
func (t Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]) MarshalJSON() ([]byte, error) {
	return tupleMarshalJSON(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10, t.F11)
}

// UnmarshalJSON unmarshals a JSON array into a [Tuple11]
func (t *Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]) UnmarshalJSON(data []byte) error {
	return tupleUnmarshalJSON(data, &t.F1, &t.F2, &t.F3, &t.F4, &t.F5, &t.F6, &t.F7, &t.F8, &t.F9, &t.F10, &t.F11)
}

// ToArray converts the [Tuple11] into an array of type [R] using 11 transformation functions from [T] to [R]
// The inverse function is [FromArray11]
func ToArray11[F1 ~func(T1) R, F2 ~func(T2) R, F3 ~func(T3) R, F4 ~func(T4) R, F5 ~func(T5) R, F6 ~func(T6) R, F7 ~func(T7) R, F8 ~func(T8) R, F9 ~func(T9) R, F10 ~func(T10) R, F11 ~func(T11) R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11) func(t Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]) []R {
	return func(t Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]) []R {
		return []R{
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
			f5(t.F5),
			f6(t.F6),
			f7(t.F7),
			f8(t.F8),
			f9(t.F9),
			f10(t.F10),
			f11(t.F11),
		}
	}
}

// FromArray converts an array of [R] into a [Tuple11] using 11 functions from [R] to [T]
// The inverse function is [ToArray11]
func FromArray11[F1 ~func(R) T1, F2 ~func(R) T2, F3 ~func(R) T3, F4 ~func(R) T4, F5 ~func(R) T5, F6 ~func(R) T6, F7 ~func(R) T7, F8 ~func(R) T8, F9 ~func(R) T9, F10 ~func(R) T10, F11 ~func(R) T11, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11) func(r []R) Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11] {
	return func(r []R) Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11] {
		return MakeTuple11(
			f1(r[0]),
			f2(r[1]),
			f3(r[2]),
			f4(r[3]),
			f5(r[4]),
			f6(r[5]),
			f7(r[6]),
			f8(r[7]),
			f9(r[8]),
			f10(r[9]),
			f11(r[10]),
		)
	}
}

// Push11 creates a [Tuple12] from a [Tuple11] by appending a constant value
func Push11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 any](value T12) func(Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]) Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12] {
	return func(t Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]) Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12] {
		return MakeTuple12(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10, t.F11, value)
	}
}

// MakeTuple12 is a function that converts its 12 parameters into a [Tuple12]
func MakeTuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 any](t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10, t11 T11, t12 T12) Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12] {
	return Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]{t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12}
}

// Tupled12 converts a function with 12 parameters into a function taking a Tuple12
// The inverse function is [Untupled12]
func Tupled12[F ~func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R any](f F) func(Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]) R {
	return func(t Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]) R {
		return f(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10, t.F11, t.F12)
	}
}

// Untupled12 converts a function with a [Tuple12] parameter into a function with 12 parameters
// The inverse function is [Tupled12]
func Untupled12[F ~func(Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]) R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R any](f F) func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) R {
	return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10, t11 T11, t12 T12) R {
		return f(MakeTuple12(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12))
	}
}

// Monoid12 creates a [Monoid] for a [Tuple12] based on 12 monoids for the contained types
func Monoid12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 any](m1 M.Monoid[T1], m2 M.Monoid[T2], m3 M.Monoid[T3], m4 M.Monoid[T4], m5 M.Monoid[T5], m6 M.Monoid[T6], m7 M.Monoid[T7], m8 M.Monoid[T8], m9 M.Monoid[T9], m10 M.Monoid[T10], m11 M.Monoid[T11], m12 M.Monoid[T12]) M.Monoid[Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]] {
	return M.MakeMonoid(func(l, r Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]) Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12] {
		return MakeTuple12(m1.Concat(l.F1, r.F1), m2.Concat(l.F2, r.F2), m3.Concat(l.F3, r.F3), m4.Concat(l.F4, r.F4), m5.Concat(l.F5, r.F5), m6.Concat(l.F6, r.F6), m7.Concat(l.F7, r.F7), m8.Concat(l.F8, r.F8), m9.Concat(l.F9, r.F9), m10.Concat(l.F10, r.F10), m11.Concat(l.F11, r.F11), m12.Concat(l.F12, r.F12))
	}, MakeTuple12(m1.Empty(), m2.Empty(), m3.Empty(), m4.Empty(), m5.Empty(), m6.Empty(), m7.Empty(), m8.Empty(), m9.Empty(), m10.Empty(), m11.Empty(), m12.Empty()))
}

// Ord12 creates n [Ord] for a [Tuple12] based on 12 [Ord]s for the contained types
func Ord12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 any](o1 O.Ord[T1], o2 O.Ord[T2], o3 O.Ord[T3], o4 O.Ord[T4], o5 O.Ord[T5], o6 O.Ord[T6], o7 O.Ord[T7], o8 O.Ord[T8], o9 O.Ord[T9], o10 O.Ord[T10], o11 O.Ord[T11], o12 O.Ord[T12]) O.Ord[Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]] {
	return O.MakeOrd(func(l, r Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]) int {
		if c := o1.Compare(l.F1, r.F1); c != 0 {
			return c
		}
		if c := o2.Compare(l.F2, r.F2); c != 0 {
			return c
		}
		if c := o3.Compare(l.F3, r.F3); c != 0 {
			return c
		}
		if c := o4.Compare(l.F4, r.F4); c != 0 {
			return c
		}
		if c := o5.Compare(l.F5, r.F5); c != 0 {
			return c
		}
		if c := o6.Compare(l.F6, r.F6); c != 0 {
			return c
		}
		if c := o7.Compare(l.F7, r.F7); c != 0 {
			return c
		}
		if c := o8.Compare(l.F8, r.F8); c != 0 {
			return c
		}
		if c := o9.Compare(l.F9, r.F9); c != 0 {
			return c
		}
		if c := o10.Compare(l.F10, r.F10); c != 0 {
			return c
		}
		if c := o11.Compare(l.F11, r.F11); c != 0 {
			return c
		}
		if c := o12.Compare(l.F12, r.F12); c != 0 {
			return c
		}
		return 0
	}, func(l, r Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]) bool {
		return o1.Equals(l.F1, r.F1) && o2.Equals(l.F2, r.F2) && o3.Equals(l.F3, r.F3) && o4.Equals(l.F4, r.F4) && o5.Equals(l.F5, r.F5) && o6.Equals(l.F6, r.F6) && o7.Equals(l.F7, r.F7) && o8.Equals(l.F8, r.F8) && o9.Equals(l.F9, r.F9) && o10.Equals(l.F10, r.F10) && o11.Equals(l.F11, r.F11) && o12.Equals(l.F12, r.F12)
	})
}

// Map12 maps each value of a [Tuple12] via a mapping function
func Map12[F1 ~func(T1) R1, F2 ~func(T2) R2, F3 ~func(T3) R3, F4 ~func(T4) R4, F5 ~func(T5) R5, F6 ~func(T6) R6, F7 ~func(T7) R7, F8 ~func(T8) R8, F9 ~func(T9) R9, F10 ~func(T10) R10, F11 ~func(T11) R11, F12 ~func(T12) R12, T1, R1, T2, R2, T3, R3, T4, R4, T5, R5, T6, R6, T7, R7, T8, R8, T9, R9, T10, R10, T11, R11, T12, R12 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12) func(Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]) Tuple12[R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12] {
	return func(t Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]) Tuple12[R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12] {
		return MakeTuple12(
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
			f5(t.F5),
			f6(t.F6),
			f7(t.F7),
			f8(t.F8),
			f9(t.F9),
			f10(t.F10),
			f11(t.F11),
			f12(t.F12),
		)
	}
}

// Replicate12 creates a [Tuple12] with all fields set to the input value `t`
func Replicate12[T any](t T) Tuple12[T, T, T, T, T, T, T, T, T, T, T, T] {
	return MakeTuple12(t, t, t, t, t, t, t, t, t, t, t, t)
}

// String prints some debug info for the [Tuple12]
func (t Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]) String() string {
	return tupleString(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10, t.F11, t.F12)
}

// MarshalJSON marshals the [Tuple12] into a JSON array
func (t Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]) MarshalJSON() ([]byte, error) {
	return tupleMarshalJSON(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10, t.F11, t.F12)
}

// UnmarshalJSON unmarshals a JSON array into a [Tuple12]
func (t *Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]) UnmarshalJSON(data []byte) error {
	return tupleUnmarshalJSON(data, &t.F1, &t.F2, &t.F3, &t.F4, &t.F5, &t.F6, &t.F7, &t.F8, &t.F9, &t.F10, &t.F11, &t.F12)
}

// ToArray converts the [Tuple12] into an array of type [R] using 12 transformation functions from [T] to [R]
// The inverse function is [FromArray12]
func ToArray12[F1 ~func(T1) R, F2 ~func(T2) R, F3 ~func(T3) R, F4 ~func(T4) R, F5 ~func(T5) R, F6 ~func(T6) R, F7 ~func(T7) R, F8 ~func(T8) R, F9 ~func(T9) R, F10 ~func(T10) R, F11 ~func(T11) R, F12 ~func(T12) R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12) func(t Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]) []R {
	return func(t Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]) []R {
		return []R{
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
			f5(t.F5),
			f6(t.F6),
			f7(t.F7),
			f8(t.F8),
			f9(t.F9),
			f10(t.F10),
			f11(t.F11),
			f12(t.F12),
		}
	}
}

// FromArray converts an array of [R] into a [Tuple12] using 12 functions from [R] to [T]
// The inverse function is [ToArray12]
func FromArray12[F1 ~func(R) T1, F2 ~func(R) T2, F3 ~func(R) T3, F4 ~func(R) T4, F5 ~func(R) T5, F6 ~func(R) T6, F7 ~func(R) T7, F8 ~func(R) T8, F9 ~func(R) T9, F10 ~func(R) T10, F11 ~func(R) T11, F12 ~func(R) T12, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12) func(r []R) Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12] {
	return func(r []R) Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12] {
		return MakeTuple12(
			f1(r[0]),
			f2(r[1]),
			f3(r[2]),
			f4(r[3]),
			f5(r[4]),
			f6(r[5]),
			f7(r[6]),
			f8(r[7]),
			f9(r[8]),
			f10(r[9]),
			f11(r[10]),
			f12(r[11]),
		)
	}
}

// Push12 creates a [Tuple13] from a [Tuple12] by appending a constant value
func Push12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 any](value T13) func(Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]) Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13] {
	return func(t Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]) Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13] {
		return MakeTuple13(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10, t.F11, t.F12, value)
	}
}

// MakeTuple13 is a function that converts its 13 parameters into a [Tuple13]
func MakeTuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 any](t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10, t11 T11, t12 T12, t13 T13) Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13] {
	return Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]{t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13}
}

// Tupled13 converts a function with 13 parameters into a function taking a Tuple13
// The inverse function is [Untupled13]
func Tupled13[F ~func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R any](f F) func(Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]) R {
	return func(t Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]) R {
		return f(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10, t.F11, t.F12, t.F13)
	}
}

// Untupled13 converts a function with a [Tuple13] parameter into a function with 13 parameters
// The inverse function is [Tupled13]
func Untupled13[F ~func(Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]) R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R any](f F) func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) R {
	return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10, t11 T11, t12 T12, t13 T13) R {
		return f(MakeTuple13(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13))
	}
}

// Monoid13 creates a [Monoid] for a [Tuple13] based on 13 monoids for the contained types
func Monoid13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 any](m1 M.Monoid[T1], m2 M.Monoid[T2], m3 M.Monoid[T3], m4 M.Monoid[T4], m5 M.Monoid[T5], m6 M.Monoid[T6], m7 M.Monoid[T7], m8 M.Monoid[T8], m9 M.Monoid[T9], m10 M.Monoid[T10], m11 M.Monoid[T11], m12 M.Monoid[T12], m13 M.Monoid[T13]) M.Monoid[Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]] {
	return M.MakeMonoid(func(l, r Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]) Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13] {
		return MakeTuple13(m1.Concat(l.F1, r.F1), m2.Concat(l.F2, r.F2), m3.Concat(l.F3, r.F3), m4.Concat(l.F4, r.F4), m5.Concat(l.F5, r.F5), m6.Concat(l.F6, r.F6), m7.Concat(l.F7, r.F7), m8.Concat(l.F8, r.F8), m9.Concat(l.F9, r.F9), m10.Concat(l.F10, r.F10), m11.Concat(l.F11, r.F11), m12.Concat(l.F12, r.F12), m13.Concat(l.F13, r.F13))
	}, MakeTuple13(m1.Empty(), m2.Empty(), m3.Empty(), m4.Empty(), m5.Empty(), m6.Empty(), m7.Empty(), m8.Empty(), m9.Empty(), m10.Empty(), m11.Empty(), m12.Empty(), m13.Empty()))
}

// Ord13 creates n [Ord] for a [Tuple13] based on 13 [Ord]s for the contained types
func Ord13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 any](o1 O.Ord[T1], o2 O.Ord[T2], o3 O.Ord[T3], o4 O.Ord[T4], o5 O.Ord[T5], o6 O.Ord[T6], o7 O.Ord[T7], o8 O.Ord[T8], o9 O.Ord[T9], o10 O.Ord[T10], o11 O.Ord[T11], o12 O.Ord[T12], o13 O.Ord[T13]) O.Ord[Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]] {
	return O.MakeOrd(func(l, r Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]) int {
		if c := o1.Compare(l.F1, r.F1); c != 0 {
			return c
		}
		if c := o2.Compare(l.F2, r.F2); c != 0 {
			return c
		}
		if c := o3.Compare(l.F3, r.F3); c != 0 {
			return c
		}
		if c := o4.Compare(l.F4, r.F4); c != 0 {
			return c
		}
		if c := o5.Compare(l.F5, r.F5); c != 0 {
			return c
		}
		if c := o6.Compare(l.F6, r.F6); c != 0 {
			return c
		}
		if c := o7.Compare(l.F7, r.F7); c != 0 {
			return c
		}
		if c := o8.Compare(l.F8, r.F8); c != 0 {
			return c
		}
		if c := o9.Compare(l.F9, r.F9); c != 0 {
			return c
		}
		if c := o10.Compare(l.F10, r.F10); c != 0 {
			return c
		}
		if c := o11.Compare(l.F11, r.F11); c != 0 {
			return c
		}
		if c := o12.Compare(l.F12, r.F12); c != 0 {
			return c
		}
		if c := o13.Compare(l.F13, r.F13); c != 0 {
			return c
		}
		return 0
	}, func(l, r Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]) bool {
		return o1.Equals(l.F1, r.F1) && o2.Equals(l.F2, r.F2) && o3.Equals(l.F3, r.F3) && o4.Equals(l.F4, r.F4) && o5.Equals(l.F5, r.F5) && o6.Equals(l.F6, r.F6) && o7.Equals(l.F7, r.F7) && o8.Equals(l.F8, r.F8) && o9.Equals(l.F9, r.F9) && o10.Equals(l.F10, r.F10) && o11.Equals(l.F11, r.F11) && o12.Equals(l.F12, r.F12) && o13.Equals(l.F13, r.F13)
	})
}

// Map13 maps each value of a [Tuple13] via a mapping function
func Map13[F1 ~func(T1) R1, F2 ~func(T2) R2, F3 ~func(T3) R3, F4 ~func(T4) R4, F5 ~func(T5) R5, F6 ~func(T6) R6, F7 ~func(T7) R7, F8 ~func(T8) R8, F9 ~func(T9) R9, F10 ~func(T10) R10, F11 ~func(T11) R11, F12 ~func(T12) R12, F13 ~func(T13) R13, T1, R1, T2, R2, T3, R3, T4, R4, T5, R5, T6, R6, T7, R7, T8, R8, T9, R9, T10, R10, T11, R11, T12, R12, T13, R13 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13) func(Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]) Tuple13[R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13] {
	return func(t Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]) Tuple13[R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13] {
		return MakeTuple13(
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
			f5(t.F5),
			f6(t.F6),
			f7(t.F7),
			f8(t.F8),
			f9(t.F9),
			f10(t.F10),
			f11(t.F11),
			f12(t.F12),
			f13(t.F13),
		)
	}
}

// Replicate13 creates a [Tuple13] with all fields set to the input value `t`
func Replicate13[T any](t T) Tuple13[T, T, T, T, T, T, T, T, T, T, T, T, T] {
	return MakeTuple13(t, t, t, t, t, t, t, t, t, t, t, t, t)
}

// String prints some debug info for the [Tuple13]
func (t Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]) String() string {
	return tupleString(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10, t.F11, t.F12, t.F13)
}

// MarshalJSON marshals the [Tuple13] into a JSON array
func (t Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]) MarshalJSON() ([]byte, error) {
	return tupleMarshalJSON(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10, t.F11, t.F12, t.F13)
}

// UnmarshalJSON unmarshals a JSON array into a [Tuple13]
func (t *Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]) UnmarshalJSON(data []byte) error {
	return tupleUnmarshalJSON(data, &t.F1, &t.F2, &t.F3, &t.F4, &t.F5, &t.F6, &t.F7, &t.F8, &t.F9, &t.F10, &t.F11, &t.F12, &t.F13)
}

// ToArray converts the [Tuple13] into an array of type [R] using 13 transformation functions from [T] to [R]
// The inverse function is [FromArray13]
func ToArray13[F1 ~func(T1) R, F2 ~func(T2) R, F3 ~func(T3) R, F4 ~func(T4) R, F5 ~func(T5) R, F6 ~func(T6) R, F7 ~func(T7) R, F8 ~func(T8) R, F9 ~func(T9) R, F10 ~func(T10) R, F11 ~func(T11) R, F12 ~func(T12) R, F13 ~func(T13) R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13) func(t Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]) []R {
	return func(t Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]) []R {
		return []R{
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
			f5(t.F5),
			f6(t.F6),
			f7(t.F7),
			f8(t.F8),
			f9(t.F9),
			f10(t.F10),
			f11(t.F11),
			f12(t.F12),
			f13(t.F13),
		}
	}
}

// FromArray converts an array of [R] into a [Tuple13] using 13 functions from [R] to [T]
// The inverse function is [ToArray13]
func FromArray13[F1 ~func(R) T1, F2 ~func(R) T2, F3 ~func(R) T3, F4 ~func(R) T4, F5 ~func(R) T5, F6 ~func(R) T6, F7 ~func(R) T7, F8 ~func(R) T8, F9 ~func(R) T9, F10 ~func(R) T10, F11 ~func(R) T11, F12 ~func(R) T12, F13 ~func(R) T13, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13) func(r []R) Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13] {
	return func(r []R) Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13] {
		return MakeTuple13(
			f1(r[0]),
			f2(r[1]),
			f3(r[2]),
			f4(r[3]),
			f5(r[4]),
			f6(r[5]),
			f7(r[6]),
			f8(r[7]),
			f9(r[8]),
			f10(r[9]),
			f11(r[10]),
			f12(r[11]),
			f13(r[12]),
		)
	}
}

// Push13 creates a [Tuple14] from a [Tuple13] by appending a constant value
func Push13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 any](value T14) func(Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]) Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14] {
	return func(t Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]) Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14] {
		return MakeTuple14(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10, t.F11, t.F12, t.F13, value)
	}
}

// MakeTuple14 is a function that converts its 14 parameters into a [Tuple14]
func MakeTuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 any](t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10, t11 T11, t12 T12, t13 T13, t14 T14) Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14] {
	return Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]{t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14}
}

// Tupled14 converts a function with 14 parameters into a function taking a Tuple14
// The inverse function is [Untupled14]
func Tupled14[F ~func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R any](f F) func(Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]) R {
	return func(t Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]) R {
		return f(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10, t.F11, t.F12, t.F13, t.F14)
	}
}

// Untupled14 converts a function with a [Tuple14] parameter into a function with 14 parameters
// The inverse function is [Tupled14]
func Untupled14[F ~func(Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]) R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R any](f F) func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) R {
	return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10, t11 T11, t12 T12, t13 T13, t14 T14) R {
		return f(MakeTuple14(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14))
	}
}

// Monoid14 creates a [Monoid] for a [Tuple14] based on 14 monoids for the contained types
func Monoid14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 any](m1 M.Monoid[T1], m2 M.Monoid[T2], m3 M.Monoid[T3], m4 M.Monoid[T4], m5 M.Monoid[T5], m6 M.Monoid[T6], m7 M.Monoid[T7], m8 M.Monoid[T8], m9 M.Monoid[T9], m10 M.Monoid[T10], m11 M.Monoid[T11], m12 M.Monoid[T12], m13 M.Monoid[T13], m14 M.Monoid[T14]) M.Monoid[Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]] {
	return M.MakeMonoid(func(l, r Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]) Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14] {
		return MakeTuple14(m1.Concat(l.F1, r.F1), m2.Concat(l.F2, r.F2), m3.Concat(l.F3, r.F3), m4.Concat(l.F4, r.F4), m5.Concat(l.F5, r.F5), m6.Concat(l.F6, r.F6), m7.Concat(l.F7, r.F7), m8.Concat(l.F8, r.F8), m9.Concat(l.F9, r.F9), m10.Concat(l.F10, r.F10), m11.Concat(l.F11, r.F11), m12.Concat(l.F12, r.F12), m13.Concat(l.F13, r.F13), m14.Concat(l.F14, r.F14))
	}, MakeTuple14(m1.Empty(), m2.Empty(), m3.Empty(), m4.Empty(), m5.Empty(), m6.Empty(), m7.Empty(), m8.Empty(), m9.Empty(), m10.Empty(), m11.Empty(), m12.Empty(), m13.Empty(), m14.Empty()))
}

// Ord14 creates n [Ord] for a [Tuple14] based on 14 [Ord]s for the contained types
func Ord14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 any](o1 O.Ord[T1], o2 O.Ord[T2], o3 O.Ord[T3], o4 O.Ord[T4], o5 O.Ord[T5], o6 O.Ord[T6], o7 O.Ord[T7], o8 O.Ord[T8], o9 O.Ord[T9], o10 O.Ord[T10], o11 O.Ord[T11], o12 O.Ord[T12], o13 O.Ord[T13], o14 O.Ord[T14]) O.Ord[Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]] {
	return O.MakeOrd(func(l, r Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]) int {
		if c := o1.Compare(l.F1, r.F1); c != 0 {
			return c
		}
		if c := o2.Compare(l.F2, r.F2); c != 0 {
			return c
		}
		if c := o3.Compare(l.F3, r.F3); c != 0 {
			return c
		}
		if c := o4.Compare(l.F4, r.F4); c != 0 {
			return c
		}
		if c := o5.Compare(l.F5, r.F5); c != 0 {
			return c
		}
		if c := o6.Compare(l.F6, r.F6); c != 0 {
			return c
		}
		if c := o7.Compare(l.F7, r.F7); c != 0 {
			return c
		}
		if c := o8.Compare(l.F8, r.F8); c != 0 {
			return c
		}
		if c := o9.Compare(l.F9, r.F9); c != 0 {
			return c
		}
		if c := o10.Compare(l.F10, r.F10); c != 0 {
			return c
		}
		if c := o11.Compare(l.F11, r.F11); c != 0 {
			return c
		}
		if c := o12.Compare(l.F12, r.F12); c != 0 {
			return c
		}
		if c := o13.Compare(l.F13, r.F13); c != 0 {
			return c
		}
		if c := o14.Compare(l.F14, r.F14); c != 0 {
			return c
		}
		return 0
	}, func(l, r Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]) bool {
		return o1.Equals(l.F1, r.F1) && o2.Equals(l.F2, r.F2) && o3.Equals(l.F3, r.F3) && o4.Equals(l.F4, r.F4) && o5.Equals(l.F5, r.F5) && o6.Equals(l.F6, r.F6) && o7.Equals(l.F7, r.F7) && o8.Equals(l.F8, r.F8) && o9.Equals(l.F9, r.F9) && o10.Equals(l.F10, r.F10) && o11.Equals(l.F11, r.F11) && o12.Equals(l.F12, r.F12) && o13.Equals(l.F13, r.F13) && o14.Equals(l.F14, r.F14)
	})
}

// Map14 maps each value of a [Tuple14] via a mapping function
func Map14[F1 ~func(T1) R1, F2 ~func(T2) R2, F3 ~func(T3) R3, F4 ~func(T4) R4, F5 ~func(T5) R5, F6 ~func(T6) R6, F7 ~func(T7) R7, F8 ~func(T8) R8, F9 ~func(T9) R9, F10 ~func(T10) R10, F11 ~func(T11) R11, F12 ~func(T12) R12, F13 ~func(T13) R13, F14 ~func(T14) R14, T1, R1, T2, R2, T3, R3, T4, R4, T5, R5, T6, R6, T7, R7, T8, R8, T9, R9, T10, R10, T11, R11, T12, R12, T13, R13, T14, R14 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13, f14 F14) func(Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]) Tuple14[R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14] {
	return func(t Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]) Tuple14[R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14] {
		return MakeTuple14(
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
			f5(t.F5),
			f6(t.F6),
			f7(t.F7),
			f8(t.F8),
			f9(t.F9),
			f10(t.F10),
			f11(t.F11),
			f12(t.F12),
			f13(t.F13),
			f14(t.F14),
		)
	}
}

// Replicate14 creates a [Tuple14] with all fields set to the input value `t`
func Replicate14[T any](t T) Tuple14[T, T, T, T, T, T, T, T, T, T, T, T, T, T] {
	return MakeTuple14(t, t, t, t, t, t, t, t, t, t, t, t, t, t)
}

// String prints some debug info for the [Tuple14]
func (t Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]) String() string {
	return tupleString(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10, t.F11, t.F12, t.F13, t.F14)
}

// MarshalJSON marshals the [Tuple14] into a JSON array
func (t Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]) MarshalJSON() ([]byte, error) {
	return tupleMarshalJSON(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10, t.F11, t.F12, t.F13, t.F14)
}

// UnmarshalJSON unmarshals a JSON array into a [Tuple14]
func (t *Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]) UnmarshalJSON(data []byte) error {
	return tupleUnmarshalJSON(data, &t.F1, &t.F2, &t.F3, &t.F4, &t.F5, &t.F6, &t.F7, &t.F8, &t.F9, &t.F10, &t.F11, &t.F12, &t.F13, &t.F14)
}

// ToArray converts the [Tuple14] into an array of type [R] using 14 transformation functions from [T] to [R]
// The inverse function is [FromArray14]
func ToArray14[F1 ~func(T1) R, F2 ~func(T2) R, F3 ~func(T3) R, F4 ~func(T4) R, F5 ~func(T5) R, F6 ~func(T6) R, F7 ~func(T7) R, F8 ~func(T8) R, F9 ~func(T9) R, F10 ~func(T10) R, F11 ~func(T11) R, F12 ~func(T12) R, F13 ~func(T13) R, F14 ~func(T14) R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13, f14 F14) func(t Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]) []R {
	return func(t Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]) []R {
		return []R{
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
			f5(t.F5),
			f6(t.F6),
			f7(t.F7),
			f8(t.F8),
			f9(t.F9),
			f10(t.F10),
			f11(t.F11),
			f12(t.F12),
			f13(t.F13),
			f14(t.F14),
		}
	}
}

// FromArray converts an array of [R] into a [Tuple14] using 14 functions from [R] to [T]
// The inverse function is [ToArray14]
func FromArray14[F1 ~func(R) T1, F2 ~func(R) T2, F3 ~func(R) T3, F4 ~func(R) T4, F5 ~func(R) T5, F6 ~func(R) T6, F7 ~func(R) T7, F8 ~func(R) T8, F9 ~func(R) T9, F10 ~func(R) T10, F11 ~func(R) T11, F12 ~func(R) T12, F13 ~func(R) T13, F14 ~func(R) T14, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13, f14 F14) func(r []R) Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14] {
	return func(r []R) Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14] {
		return MakeTuple14(
			f1(r[0]),
			f2(r[1]),
			f3(r[2]),
			f4(r[3]),
			f5(r[4]),
			f6(r[5]),
			f7(r[6]),
			f8(r[7]),
			f9(r[8]),
			f10(r[9]),
			f11(r[10]),
			f12(r[11]),
			f13(r[12]),
			f14(r[13]),
		)
	}
}

// Push14 creates a [Tuple15] from a [Tuple14] by appending a constant value
func Push14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 any](value T15) func(Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]) Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15] {
	return func(t Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]) Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15] {
		return MakeTuple15(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10, t.F11, t.F12, t.F13, t.F14, value)
	}
}

// MakeTuple15 is a function that converts its 15 parameters into a [Tuple15]
func MakeTuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 any](t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10, t11 T11, t12 T12, t13 T13, t14 T14, t15 T15) Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15] {
	return Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]{t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15}
}

// Tupled15 converts a function with 15 parameters into a function taking a Tuple15
// The inverse function is [Untupled15]
func Tupled15[F ~func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R any](f F) func(Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]) R {
	return func(t Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]) R {
		return f(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10, t.F11, t.F12, t.F13, t.F14, t.F15)
	}
}

// Untupled15 converts a function with a [Tuple15] parameter into a function with 15 parameters
// The inverse function is [Tupled15]
func Untupled15[F ~func(Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]) R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R any](f F) func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) R {
	return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10, t11 T11, t12 T12, t13 T13, t14 T14, t15 T15) R {
		return f(MakeTuple15(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15))
	}
}

// Monoid15 creates a [Monoid] for a [Tuple15] based on 15 monoids for the contained types
func Monoid15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 any](m1 M.Monoid[T1], m2 M.Monoid[T2], m3 M.Monoid[T3], m4 M.Monoid[T4], m5 M.Monoid[T5], m6 M.Monoid[T6], m7 M.Monoid[T7], m8 M.Monoid[T8], m9 M.Monoid[T9], m10 M.Monoid[T10], m11 M.Monoid[T11], m12 M.Monoid[T12], m13 M.Monoid[T13], m14 M.Monoid[T14], m15 M.Monoid[T15]) M.Monoid[Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]] {
	return M.MakeMonoid(func(l, r Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]) Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15] {
		return MakeTuple15(m1.Concat(l.F1, r.F1), m2.Concat(l.F2, r.F2), m3.Concat(l.F3, r.F3), m4.Concat(l.F4, r.F4), m5.Concat(l.F5, r.F5), m6.Concat(l.F6, r.F6), m7.Concat(l.F7, r.F7), m8.Concat(l.F8, r.F8), m9.Concat(l.F9, r.F9), m10.Concat(l.F10, r.F10), m11.Concat(l.F11, r.F11), m12.Concat(l.F12, r.F12), m13.Concat(l.F13, r.F13), m14.Concat(l.F14, r.F14), m15.Concat(l.F15, r.F15))
	}, MakeTuple15(m1.Empty(), m2.Empty(), m3.Empty(), m4.Empty(), m5.Empty(), m6.Empty(), m7.Empty(), m8.Empty(), m9.Empty(), m10.Empty(), m11.Empty(), m12.Empty(), m13.Empty(), m14.Empty(), m15.Empty()))
}

// Ord15 creates n [Ord] for a [Tuple15] based on 15 [Ord]s for the contained types
func Ord15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 any](o1 O.Ord[T1], o2 O.Ord[T2], o3 O.Ord[T3], o4 O.Ord[T4], o5 O.Ord[T5], o6 O.Ord[T6], o7 O.Ord[T7], o8 O.Ord[T8], o9 O.Ord[T9], o10 O.Ord[T10], o11 O.Ord[T11], o12 O.Ord[T12], o13 O.Ord[T13], o14 O.Ord[T14], o15 O.Ord[T15]) O.Ord[Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]] {
	return O.MakeOrd(func(l, r Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]) int {
		if c := o1.Compare(l.F1, r.F1); c != 0 {
			return c
		}
		if c := o2.Compare(l.F2, r.F2); c != 0 {
			return c
		}
		if c := o3.Compare(l.F3, r.F3); c != 0 {
			return c
		}
		if c := o4.Compare(l.F4, r.F4); c != 0 {
			return c
		}
		if c := o5.Compare(l.F5, r.F5); c != 0 {
			return c
		}
		if c := o6.Compare(l.F6, r.F6); c != 0 {
			return c
		}
		if c := o7.Compare(l.F7, r.F7); c != 0 {
			return c
		}
		if c := o8.Compare(l.F8, r.F8); c != 0 {
			return c
		}
		if c := o9.Compare(l.F9, r.F9); c != 0 {
			return c
		}
		if c := o10.Compare(l.F10, r.F10); c != 0 {
			return c
		}
		if c := o11.Compare(l.F11, r.F11); c != 0 {
			return c
		}
		if c := o12.Compare(l.F12, r.F12); c != 0 {
			return c
		}
		if c := o13.Compare(l.F13, r.F13); c != 0 {
			return c
		}
		if c := o14.Compare(l.F14, r.F14); c != 0 {
			return c
		}
		if c := o15.Compare(l.F15, r.F15); c != 0 {
			return c
		}
		return 0
	}, func(l, r Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]) bool {
		return o1.Equals(l.F1, r.F1) && o2.Equals(l.F2, r.F2) && o3.Equals(l.F3, r.F3) && o4.Equals(l.F4, r.F4) && o5.Equals(l.F5, r.F5) && o6.Equals(l.F6, r.F6) && o7.Equals(l.F7, r.F7) && o8.Equals(l.F8, r.F8) && o9.Equals(l.F9, r.F9) && o10.Equals(l.F10, r.F10) && o11.Equals(l.F11, r.F11) && o12.Equals(l.F12, r.F12) && o13.Equals(l.F13, r.F13) && o14.Equals(l.F14, r.F14) && o15.Equals(l.F15, r.F15)
	})
}

// Map15 maps each value of a [Tuple15] via a mapping function
func Map15[F1 ~func(T1) R1, F2 ~func(T2) R2, F3 ~func(T3) R3, F4 ~func(T4) R4, F5 ~func(T5) R5, F6 ~func(T6) R6, F7 ~func(T7) R7, F8 ~func(T8) R8, F9 ~func(T9) R9, F10 ~func(T10) R10, F11 ~func(T11) R11, F12 ~func(T12) R12, F13 ~func(T13) R13, F14 ~func(T14) R14, F15 ~func(T15) R15, T1, R1, T2, R2, T3, R3, T4, R4, T5, R5, T6, R6, T7, R7, T8, R8, T9, R9, T10, R10, T11, R11, T12, R12, T13, R13, T14, R14, T15, R15 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13, f14 F14, f15 F15) func(Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]) Tuple15[R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15] {
	return func(t Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]) Tuple15[R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15] {
		return MakeTuple15(
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
			f5(t.F5),
			f6(t.F6),
			f7(t.F7),
			f8(t.F8),
			f9(t.F9),
			f10(t.F10),
			f11(t.F11),
			f12(t.F12),
			f13(t.F13),
			f14(t.F14),
			f15(t.F15),
		)
	}
}

// Replicate15 creates a [Tuple15] with all fields set to the input value `t`
func Replicate15[T any](t T) Tuple15[T, T, T, T, T, T, T, T, T, T, T, T, T, T, T] {
	return MakeTuple15(t, t, t, t, t, t, t, t, t, t, t, t, t, t, t)
}

// String prints some debug info for the [Tuple15]
func (t Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]) String() string {
	return tupleString(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10, t.F11, t.F12, t.F13, t.F14, t.F15)
}

// MarshalJSON marshals the [Tuple15] into a JSON array
func (t Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]) MarshalJSON() ([]byte, error) {
	return tupleMarshalJSON(t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10, t.F11, t.F12, t.F13, t.F14, t.F15)
}

// UnmarshalJSON unmarshals a JSON array into a [Tuple15]
func (t *Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]) UnmarshalJSON(data []byte) error {
	return tupleUnmarshalJSON(data, &t.F1, &t.F2, &t.F3, &t.F4, &t.F5, &t.F6, &t.F7, &t.F8, &t.F9, &t.F10, &t.F11, &t.F12, &t.F13, &t.F14, &t.F15)
}

// ToArray converts the [Tuple15] into an array of type [R] using 15 transformation functions from [T] to [R]
// The inverse function is [FromArray15]
func ToArray15[F1 ~func(T1) R, F2 ~func(T2) R, F3 ~func(T3) R, F4 ~func(T4) R, F5 ~func(T5) R, F6 ~func(T6) R, F7 ~func(T7) R, F8 ~func(T8) R, F9 ~func(T9) R, F10 ~func(T10) R, F11 ~func(T11) R, F12 ~func(T12) R, F13 ~func(T13) R, F14 ~func(T14) R, F15 ~func(T15) R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13, f14 F14, f15 F15) func(t Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]) []R {
	return func(t Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]) []R {
		return []R{
			f1(t.F1),
			f2(t.F2),
			f3(t.F3),
			f4(t.F4),
			f5(t.F5),
			f6(t.F6),
			f7(t.F7),
			f8(t.F8),
			f9(t.F9),
			f10(t.F10),
			f11(t.F11),
			f12(t.F12),
			f13(t.F13),
			f14(t.F14),
			f15(t.F15),
		}
	}
}

// FromArray converts an array of [R] into a [Tuple15] using 15 functions from [R] to [T]
// The inverse function is [ToArray15]
func FromArray15[F1 ~func(R) T1, F2 ~func(R) T2, F3 ~func(R) T3, F4 ~func(R) T4, F5 ~func(R) T5, F6 ~func(R) T6, F7 ~func(R) T7, F8 ~func(R) T8, F9 ~func(R) T9, F10 ~func(R) T10, F11 ~func(R) T11, F12 ~func(R) T12, F13 ~func(R) T13, F14 ~func(R) T14, F15 ~func(R) T15, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13, f14 F14, f15 F15) func(r []R) Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15] {
	return func(r []R) Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15] {
		return MakeTuple15(
			f1(r[0]),
			f2(r[1]),
			f3(r[2]),
			f4(r[3]),
			f5(r[4]),
			f6(r[5]),
			f7(r[6]),
			f8(r[7]),
			f9(r[8]),
			f10(r[9]),
			f11(r[10]),
			f12(r[11]),
			f13(r[12]),
			f14(r[13]),
			f15(r[14]),
		)
	}
}
