diff --git a/cli/tuple.go b/cli/tuple.go index ddc618f..bf2c96e 100644 --- a/cli/tuple.go +++ b/cli/tuple.go @@ -405,8 +405,6 @@ func generateTupleHelpers(filename string, count int) error { fmt.Fprintf(f, ` import ( - "fmt" - "encoding/json" M "github.com/IBM/fp-go/monoid" O "github.com/IBM/fp-go/ord" ) @@ -457,7 +455,7 @@ func generateTupleMarshal(f *os.File, i int) { fmt.Fprintf(f, "func (t ") writeTupleType(f, "T", i) fmt.Fprintf(f, ") MarshalJSON() ([]byte, error) {\n") - fmt.Fprintf(f, " return json.Marshal([]any{") + fmt.Fprintf(f, " return tupleMarshalJSON(") // function prototypes for j := 1; j <= i; j++ { if j > 1 { @@ -465,7 +463,7 @@ func generateTupleMarshal(f *os.File, i int) { } fmt.Fprintf(f, "t.F%d", j) } - fmt.Fprintf(f, "})\n") + fmt.Fprintf(f, ")\n") fmt.Fprintf(f, "}\n") } @@ -475,19 +473,12 @@ func generateTupleUnmarshal(f *os.File, i int) { fmt.Fprintf(f, "func (t *") writeTupleType(f, "T", i) fmt.Fprintf(f, ") UnmarshalJSON(data []byte) error {\n") - fmt.Fprintf(f, " var tmp []json.RawMessage\n") - fmt.Fprintf(f, " if err := json.Unmarshal(data, &tmp); err != nil {return err}\n") - fmt.Fprintf(f, " l := len(tmp)\n") - // unmarshal fields - for j := 1; j <= i; j++ { - fmt.Fprintf(f, " if l > %d {\n", j-1) - fmt.Fprintf(f, " if err := json.Unmarshal(tmp[%d], &t.F%d); err != nil {return err}\n", j-1, j) - } - fmt.Fprintf(f, " ") + fmt.Fprintf(f, " return tupleUnmarshalJSON(data") + // function prototypes for j := 1; j <= i; j++ { - fmt.Fprintf(f, "}") + fmt.Fprintf(f, ", &t.F%d", j) } - fmt.Fprintf(f, "\n return nil\n") + fmt.Fprintf(f, ")\n") fmt.Fprintf(f, "}\n") } @@ -570,30 +561,13 @@ func generateTupleString(f *os.File, i int) { writeTupleType(f, "T", i) fmt.Fprintf(f, ") String() string {\n") // convert to string - fmt.Fprintf(f, " return fmt.Sprintf(\"Tuple%d[", i) - for j := 1; j <= i; j++ { - if j > 1 { - fmt.Fprintf(f, ", ") - } - fmt.Fprintf(f, "%s", "%T") - } - fmt.Fprintf(f, "](") - for j := 1; j <= i; j++ { - if j > 1 { - fmt.Fprintf(f, ", ") - } - fmt.Fprintf(f, "%s", "%v") - } - fmt.Fprintf(f, ")\", ") + fmt.Fprint(f, " return tupleString(") for j := 1; j <= i; j++ { if j > 1 { fmt.Fprintf(f, ", ") } fmt.Fprintf(f, "t.F%d", j) } - for j := 1; j <= i; j++ { - fmt.Fprintf(f, ", t.F%d", j) - } fmt.Fprintf(f, ")\n") fmt.Fprintf(f, "}\n") } diff --git a/tuple/gen.go b/tuple/gen.go index 54517b1..62115e1 100644 --- a/tuple/gen.go +++ b/tuple/gen.go @@ -1,1655 +1,1219 @@ // Code generated by go generate; DO NOT EDIT. // This file was generated by robots at -// 2023-10-23 08:31:19.0449107 +0200 CEST m=+0.023307601 +// 2024-02-08 08:36:32.8883679 +0100 CET m=+0.008054801 package tuple + import ( - "encoding/json" - "fmt" M "github.com/IBM/fp-go/monoid" - O "github.com/IBM/fp-go/ord" + O "github.com/IBM/fp-go/ord" ) // Tuple1 is a struct that carries 1 independently typed values type Tuple1[T1 any] struct { - F1 T1 + F1 T1 } // Tuple2 is a struct that carries 2 independently typed values type Tuple2[T1, T2 any] struct { - F1 T1 - F2 T2 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + F1 T1 + F2 T2 + F3 T3 + F4 T4 + F5 T5 + F6 T6 + F7 T7 + F8 T8 + F9 T9 + F10 T10 } // MakeTuple1 is a function that converts its 1 parameters into a [Tuple1] func MakeTuple1[T1 any](t1 T1) Tuple1[T1] { - return Tuple1[T1]{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) - } + 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)) - } + 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())) + 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) - }) + 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), - ) - } + 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) + return MakeTuple1(t) } // String prints some debug info for the [Tuple1] func (t Tuple1[T1]) String() string { - return fmt.Sprintf("Tuple1[%T](%v)", t.F1, t.F1) + return tupleString(t.F1) } // MarshalJSON marshals the [Tuple1] into a JSON array func (t Tuple1[T1]) MarshalJSON() ([]byte, error) { - return json.Marshal([]any{t.F1}) + return tupleMarshalJSON(t.F1) } // UnmarshalJSON unmarshals a JSON array into a [Tuple1] func (t *Tuple1[T1]) UnmarshalJSON(data []byte) error { - var tmp []json.RawMessage - if err := json.Unmarshal(data, &tmp); err != nil { - return err - } - l := len(tmp) - if l > 0 { - if err := json.Unmarshal(tmp[0], &t.F1); err != nil { - return err - } - } - return nil + 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), - } - } + 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]), - ) - } + 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) - } + 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} + 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) - } + 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)) - } + 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())) + 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) - }) + 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), - ) - } + 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) + return MakeTuple2(t, t) } // String prints some debug info for the [Tuple2] func (t Tuple2[T1, T2]) String() string { - return fmt.Sprintf("Tuple2[%T, %T](%v, %v)", t.F1, t.F2, t.F1, t.F2) + return tupleString(t.F1, t.F2) } // MarshalJSON marshals the [Tuple2] into a JSON array func (t Tuple2[T1, T2]) MarshalJSON() ([]byte, error) { - return json.Marshal([]any{t.F1, t.F2}) + return tupleMarshalJSON(t.F1, t.F2) } // UnmarshalJSON unmarshals a JSON array into a [Tuple2] func (t *Tuple2[T1, T2]) UnmarshalJSON(data []byte) error { - var tmp []json.RawMessage - if err := json.Unmarshal(data, &tmp); err != nil { - return err - } - l := len(tmp) - if l > 0 { - if err := json.Unmarshal(tmp[0], &t.F1); err != nil { - return err - } - if l > 1 { - if err := json.Unmarshal(tmp[1], &t.F2); err != nil { - return err - } - } - } - return nil + 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), - } - } + 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]), - ) - } + 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) - } + 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} + 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) - } + 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)) - } + 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())) + 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) - }) + 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), - ) - } + 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) + return MakeTuple3(t, t, t) } // String prints some debug info for the [Tuple3] func (t Tuple3[T1, T2, T3]) String() string { - return fmt.Sprintf("Tuple3[%T, %T, %T](%v, %v, %v)", t.F1, t.F2, t.F3, t.F1, t.F2, t.F3) + 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 json.Marshal([]any{t.F1, t.F2, t.F3}) + 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 { - var tmp []json.RawMessage - if err := json.Unmarshal(data, &tmp); err != nil { - return err - } - l := len(tmp) - if l > 0 { - if err := json.Unmarshal(tmp[0], &t.F1); err != nil { - return err - } - if l > 1 { - if err := json.Unmarshal(tmp[1], &t.F2); err != nil { - return err - } - if l > 2 { - if err := json.Unmarshal(tmp[2], &t.F3); err != nil { - return err - } - } - } - } - return nil + 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), - } - } + 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]), - ) - } + 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) - } + 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} + 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) - } + 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)) - } + 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())) + 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) - }) + 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), - ) - } + 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) + return MakeTuple4(t, t, t, t) } // String prints some debug info for the [Tuple4] func (t Tuple4[T1, T2, T3, T4]) String() string { - return fmt.Sprintf("Tuple4[%T, %T, %T, %T](%v, %v, %v, %v)", t.F1, t.F2, t.F3, t.F4, t.F1, t.F2, t.F3, t.F4) + 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 json.Marshal([]any{t.F1, t.F2, t.F3, t.F4}) + 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 { - var tmp []json.RawMessage - if err := json.Unmarshal(data, &tmp); err != nil { - return err - } - l := len(tmp) - if l > 0 { - if err := json.Unmarshal(tmp[0], &t.F1); err != nil { - return err - } - if l > 1 { - if err := json.Unmarshal(tmp[1], &t.F2); err != nil { - return err - } - if l > 2 { - if err := json.Unmarshal(tmp[2], &t.F3); err != nil { - return err - } - if l > 3 { - if err := json.Unmarshal(tmp[3], &t.F4); err != nil { - return err - } - } - } - } - } - return nil + 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), - } - } + 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]), - ) - } + 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) - } + 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} + 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) - } + 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)) - } + 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())) + 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) - }) + 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), - ) - } + 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) + 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 fmt.Sprintf("Tuple5[%T, %T, %T, %T, %T](%v, %v, %v, %v, %v)", t.F1, t.F2, t.F3, t.F4, t.F5, t.F1, t.F2, t.F3, t.F4, t.F5) + 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 json.Marshal([]any{t.F1, t.F2, t.F3, t.F4, t.F5}) + 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 { - var tmp []json.RawMessage - if err := json.Unmarshal(data, &tmp); err != nil { - return err - } - l := len(tmp) - if l > 0 { - if err := json.Unmarshal(tmp[0], &t.F1); err != nil { - return err - } - if l > 1 { - if err := json.Unmarshal(tmp[1], &t.F2); err != nil { - return err - } - if l > 2 { - if err := json.Unmarshal(tmp[2], &t.F3); err != nil { - return err - } - if l > 3 { - if err := json.Unmarshal(tmp[3], &t.F4); err != nil { - return err - } - if l > 4 { - if err := json.Unmarshal(tmp[4], &t.F5); err != nil { - return err - } - } - } - } - } - } - return nil + 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), - } - } + 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]), - ) - } + 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) - } + 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} + 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) - } + 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)) - } + 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())) + 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) - }) + 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), - ) - } + 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) + 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 fmt.Sprintf("Tuple6[%T, %T, %T, %T, %T, %T](%v, %v, %v, %v, %v, %v)", t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F1, t.F2, t.F3, t.F4, t.F5, t.F6) + 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 json.Marshal([]any{t.F1, t.F2, t.F3, t.F4, t.F5, t.F6}) + 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 { - var tmp []json.RawMessage - if err := json.Unmarshal(data, &tmp); err != nil { - return err - } - l := len(tmp) - if l > 0 { - if err := json.Unmarshal(tmp[0], &t.F1); err != nil { - return err - } - if l > 1 { - if err := json.Unmarshal(tmp[1], &t.F2); err != nil { - return err - } - if l > 2 { - if err := json.Unmarshal(tmp[2], &t.F3); err != nil { - return err - } - if l > 3 { - if err := json.Unmarshal(tmp[3], &t.F4); err != nil { - return err - } - if l > 4 { - if err := json.Unmarshal(tmp[4], &t.F5); err != nil { - return err - } - if l > 5 { - if err := json.Unmarshal(tmp[5], &t.F6); err != nil { - return err - } - } - } - } - } - } - } - return nil + 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), - } - } + 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]), - ) - } + 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) - } + 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} + 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) - } + 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)) - } + 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())) + 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) - }) + 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), - ) - } + 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) + 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 fmt.Sprintf("Tuple7[%T, %T, %T, %T, %T, %T, %T](%v, %v, %v, %v, %v, %v, %v)", t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7) + 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 json.Marshal([]any{t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7}) + 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 { - var tmp []json.RawMessage - if err := json.Unmarshal(data, &tmp); err != nil { - return err - } - l := len(tmp) - if l > 0 { - if err := json.Unmarshal(tmp[0], &t.F1); err != nil { - return err - } - if l > 1 { - if err := json.Unmarshal(tmp[1], &t.F2); err != nil { - return err - } - if l > 2 { - if err := json.Unmarshal(tmp[2], &t.F3); err != nil { - return err - } - if l > 3 { - if err := json.Unmarshal(tmp[3], &t.F4); err != nil { - return err - } - if l > 4 { - if err := json.Unmarshal(tmp[4], &t.F5); err != nil { - return err - } - if l > 5 { - if err := json.Unmarshal(tmp[5], &t.F6); err != nil { - return err - } - if l > 6 { - if err := json.Unmarshal(tmp[6], &t.F7); err != nil { - return err - } - } - } - } - } - } - } - } - return nil + 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), - } - } + 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]), - ) - } + 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) - } + 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} + 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) - } + 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)) - } + 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())) + 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) - }) + 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), - ) - } + 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) + 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 fmt.Sprintf("Tuple8[%T, %T, %T, %T, %T, %T, %T, %T](%v, %v, %v, %v, %v, %v, %v, %v)", t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8) + 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 json.Marshal([]any{t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8}) + 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 { - var tmp []json.RawMessage - if err := json.Unmarshal(data, &tmp); err != nil { - return err - } - l := len(tmp) - if l > 0 { - if err := json.Unmarshal(tmp[0], &t.F1); err != nil { - return err - } - if l > 1 { - if err := json.Unmarshal(tmp[1], &t.F2); err != nil { - return err - } - if l > 2 { - if err := json.Unmarshal(tmp[2], &t.F3); err != nil { - return err - } - if l > 3 { - if err := json.Unmarshal(tmp[3], &t.F4); err != nil { - return err - } - if l > 4 { - if err := json.Unmarshal(tmp[4], &t.F5); err != nil { - return err - } - if l > 5 { - if err := json.Unmarshal(tmp[5], &t.F6); err != nil { - return err - } - if l > 6 { - if err := json.Unmarshal(tmp[6], &t.F7); err != nil { - return err - } - if l > 7 { - if err := json.Unmarshal(tmp[7], &t.F8); err != nil { - return err - } - } - } - } - } - } - } - } - } - return nil + 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), - } - } + 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]), - ) - } + 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) - } + 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} + 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) - } + 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)) - } + 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())) + 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) - }) + 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), - ) - } + 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) + 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 fmt.Sprintf("Tuple9[%T, %T, %T, %T, %T, %T, %T, %T, %T](%v, %v, %v, %v, %v, %v, %v, %v, %v)", t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9) + 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 json.Marshal([]any{t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9}) + 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 { - var tmp []json.RawMessage - if err := json.Unmarshal(data, &tmp); err != nil { - return err - } - l := len(tmp) - if l > 0 { - if err := json.Unmarshal(tmp[0], &t.F1); err != nil { - return err - } - if l > 1 { - if err := json.Unmarshal(tmp[1], &t.F2); err != nil { - return err - } - if l > 2 { - if err := json.Unmarshal(tmp[2], &t.F3); err != nil { - return err - } - if l > 3 { - if err := json.Unmarshal(tmp[3], &t.F4); err != nil { - return err - } - if l > 4 { - if err := json.Unmarshal(tmp[4], &t.F5); err != nil { - return err - } - if l > 5 { - if err := json.Unmarshal(tmp[5], &t.F6); err != nil { - return err - } - if l > 6 { - if err := json.Unmarshal(tmp[6], &t.F7); err != nil { - return err - } - if l > 7 { - if err := json.Unmarshal(tmp[7], &t.F8); err != nil { - return err - } - if l > 8 { - if err := json.Unmarshal(tmp[8], &t.F9); err != nil { - return err - } - } - } - } - } - } - } - } - } - } - return nil + 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), - } - } + 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]), - ) - } + 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) - } + 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} + 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) - } + 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)) - } + 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())) + 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) - }) + 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), - ) - } + 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) + 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 fmt.Sprintf("Tuple10[%T, %T, %T, %T, %T, %T, %T, %T, %T, %T](%v, %v, %v, %v, %v, %v, %v, %v, %v, %v)", t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10, t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10) + 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 json.Marshal([]any{t.F1, t.F2, t.F3, t.F4, t.F5, t.F6, t.F7, t.F8, t.F9, t.F10}) + 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 { - var tmp []json.RawMessage - if err := json.Unmarshal(data, &tmp); err != nil { - return err - } - l := len(tmp) - if l > 0 { - if err := json.Unmarshal(tmp[0], &t.F1); err != nil { - return err - } - if l > 1 { - if err := json.Unmarshal(tmp[1], &t.F2); err != nil { - return err - } - if l > 2 { - if err := json.Unmarshal(tmp[2], &t.F3); err != nil { - return err - } - if l > 3 { - if err := json.Unmarshal(tmp[3], &t.F4); err != nil { - return err - } - if l > 4 { - if err := json.Unmarshal(tmp[4], &t.F5); err != nil { - return err - } - if l > 5 { - if err := json.Unmarshal(tmp[5], &t.F6); err != nil { - return err - } - if l > 6 { - if err := json.Unmarshal(tmp[6], &t.F7); err != nil { - return err - } - if l > 7 { - if err := json.Unmarshal(tmp[7], &t.F8); err != nil { - return err - } - if l > 8 { - if err := json.Unmarshal(tmp[8], &t.F9); err != nil { - return err - } - if l > 9 { - if err := json.Unmarshal(tmp[9], &t.F10); err != nil { - return err - } - } - } - } - } - } - } - } - } - } - } - return nil + 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), - } - } + 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]), - ) - } + 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]), + ) + } } diff --git a/tuple/tuple.go b/tuple/tuple.go index ec48cf5..f052daf 100644 --- a/tuple/tuple.go +++ b/tuple/tuple.go @@ -17,6 +17,14 @@ // consider to use arrays for simplicity package tuple +import ( + "encoding/json" + "fmt" + "strings" + + N "github.com/IBM/fp-go/number" +) + func Of[T1 any](t T1) Tuple1[T1] { return MakeTuple1(t) } @@ -46,3 +54,31 @@ func BiMap[E, G, A, B any](mapSnd func(E) G, mapFst func(A) B) func(Tuple2[A, E] return MakeTuple2(mapFst(First(t)), mapSnd(Second(t))) } } + +// marshalJSON marshals the tuple into a JSON array +func tupleMarshalJSON(src ...any) ([]byte, error) { + return json.Marshal(src) +} + +// tupleUnmarshalJSON unmarshals a JSON array into a tuple +func tupleUnmarshalJSON(data []byte, dst ...any) error { + var src []json.RawMessage + if err := json.Unmarshal(data, &src); err != nil { + return err + } + l := N.Min(len(src), len(dst)) + // unmarshal + for i := 0; i < l; i++ { + if err := json.Unmarshal(src[i], dst[i]); err != nil { + return err + } + } + // successfully decoded the tuple + return nil +} + +// tupleString converts a tuple to a string +func tupleString(src ...any) string { + l := len(src) + return fmt.Sprintf("Tuple%d[%s](%s)", l, fmt.Sprintf(strings.Repeat(", %T", l)[2:], src...), fmt.Sprintf(strings.Repeat(", %v", l)[2:], src...)) +}