diff --git a/cli/contextreaderioeither.go b/cli/contextreaderioeither.go index 059e629..546c1e7 100644 --- a/cli/contextreaderioeither.go +++ b/cli/contextreaderioeither.go @@ -365,6 +365,70 @@ func generateContextReaderIOEitherEitherize(f, fg *os.File, i int) { fmt.Fprintln(fg, "}") } +func generateContextReaderIOEitherUneitherize(f, fg *os.File, i int) { + // non generic version + fmt.Fprintf(f, "\n// Uneitherize%d converts a function with %d parameters returning a [ReaderIOEither[R]] into a function with %d parameters returning a tuple.\n// The first parameter is considered to be the [context.Context].\n", i, i+1, i) + fmt.Fprintf(f, "func Uneitherize%d[F ~func(", i) + for j := 0; j < i; j++ { + if j > 0 { + fmt.Fprintf(f, ", ") + } + fmt.Fprintf(f, "T%d", j) + } + fmt.Fprintf(f, ") ReaderIOEither[R]") + for j := 0; j < i; j++ { + fmt.Fprintf(f, ", T%d", j) + } + fmt.Fprintf(f, ", R any](f F) func(context.Context") + for j := 0; j < i; j++ { + fmt.Fprintf(f, ", T%d", j) + } + fmt.Fprintf(f, ") (R, error) {\n") + fmt.Fprintf(f, " return G.Uneitherize%d[ReaderIOEither[R]", i) + + fmt.Fprintf(f, ", func(context.Context") + for j := 0; j < i; j++ { + fmt.Fprintf(f, ", T%d", j) + } + fmt.Fprintf(f, ")(R, error)](f)\n") + fmt.Fprintln(f, "}") + + // generic version + fmt.Fprintf(fg, "\n// Uneitherize%d converts a function with %d parameters returning a [GRA] into a function with %d parameters returning a tuple.\n// The first parameter is considered to be the [context.Context].\n", i, i, i) + fmt.Fprintf(fg, "func Uneitherize%d[GRA ~func(context.Context) GIOA, F ~func(context.Context", i) + for j := 0; j < i; j++ { + fmt.Fprintf(fg, ", T%d", j) + } + fmt.Fprintf(fg, ") (R, error), GIOA ~func() E.Either[error, R]") + for j := 0; j < i; j++ { + fmt.Fprintf(fg, ", T%d", j) + } + fmt.Fprintf(fg, ", R any](f func(") + for j := 0; j < i; j++ { + if j > 0 { + fmt.Fprintf(fg, ", ") + } + fmt.Fprintf(fg, "T%d", j) + } + fmt.Fprintf(fg, ") GRA) F {\n") + + fmt.Fprintf(fg, " return func(c context.Context") + for j := 0; j < i; j++ { + fmt.Fprintf(fg, ", t%d T%d", j, j) + } + fmt.Fprintf(fg, ") (R, error) {\n") + fmt.Fprintf(fg, " return E.UnwrapError(f(") + for j := 0; j < i; j++ { + if j > 0 { + fmt.Fprintf(fg, ", ") + } + fmt.Fprintf(fg, "t%d", j) + } + fmt.Fprintf(fg, ")(c)())\n") + fmt.Fprintf(fg, " }\n") + fmt.Fprintf(fg, "}\n") +} + func generateContextReaderIOEitherHelpers(filename string, count int) error { dir, err := os.Getwd() if err != nil { @@ -420,10 +484,12 @@ import ( `) generateContextReaderIOEitherEitherize(f, fg, 0) + generateContextReaderIOEitherUneitherize(f, fg, 0) for i := 1; i <= count; i++ { // eitherize generateContextReaderIOEitherEitherize(f, fg, i) + generateContextReaderIOEitherUneitherize(f, fg, i) // sequenceT generateContextReaderIOEitherSequenceT("")(f, fg, i) generateContextReaderIOEitherSequenceT("Seq")(f, fg, i) diff --git a/cli/templates/functions.go b/cli/templates/functions.go new file mode 100644 index 0000000..abec6b0 --- /dev/null +++ b/cli/templates/functions.go @@ -0,0 +1,15 @@ +package templates + +import ( + "text/template" + + E "github.com/IBM/fp-go/either" +) + +var ( + templateFunctions = template.FuncMap{} +) + +func Parse(name, tmpl string) E.Either[error, *template.Template] { + return E.TryCatchError(template.New(name).Funcs(templateFunctions).Parse(tmpl)) +} diff --git a/context/readerioeither/gen.go b/context/readerioeither/gen.go index e718d1a..bf5394e 100644 --- a/context/readerioeither/gen.go +++ b/context/readerioeither/gen.go @@ -2,7 +2,7 @@ package readerioeither // Code generated by go generate; DO NOT EDIT. // This file was generated by robots at -// 2024-02-29 16:18:46.1201552 +0100 CET m=+0.020664901 +// 2024-05-24 22:24:01.4250895 +0200 CEST m=+0.014515801 import ( "context" @@ -17,12 +17,24 @@ func Eitherize0[F ~func(context.Context) (R, error), R any](f F) func() ReaderIO return G.Eitherize0[ReaderIOEither[R]](f) } +// Uneitherize0 converts a function with 1 parameters returning a [ReaderIOEither[R]] into a function with 0 parameters returning a tuple. +// The first parameter is considered to be the [context.Context]. +func Uneitherize0[F ~func() ReaderIOEither[R], R any](f F) func(context.Context) (R, error) { + return G.Uneitherize0[ReaderIOEither[R], func(context.Context) (R, error)](f) +} + // Eitherize1 converts a function with 1 parameters returning a tuple into a function with 1 parameters returning a [ReaderIOEither[R]] // The inverse function is [Uneitherize1] func Eitherize1[F ~func(context.Context, T0) (R, error), T0, R any](f F) func(T0) ReaderIOEither[R] { return G.Eitherize1[ReaderIOEither[R]](f) } +// Uneitherize1 converts a function with 2 parameters returning a [ReaderIOEither[R]] into a function with 1 parameters returning a tuple. +// The first parameter is considered to be the [context.Context]. +func Uneitherize1[F ~func(T0) ReaderIOEither[R], T0, R any](f F) func(context.Context, T0) (R, error) { + return G.Uneitherize1[ReaderIOEither[R], func(context.Context, T0) (R, error)](f) +} + // SequenceT1 converts 1 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple1]. func SequenceT1[T1 any](t1 ReaderIOEither[T1]) ReaderIOEither[T.Tuple1[T1]] { return G.SequenceT1[ReaderIOEither[T.Tuple1[T1]]](t1) @@ -74,6 +86,12 @@ func Eitherize2[F ~func(context.Context, T0, T1) (R, error), T0, T1, R any](f F) return G.Eitherize2[ReaderIOEither[R]](f) } +// Uneitherize2 converts a function with 3 parameters returning a [ReaderIOEither[R]] into a function with 2 parameters returning a tuple. +// The first parameter is considered to be the [context.Context]. +func Uneitherize2[F ~func(T0, T1) ReaderIOEither[R], T0, T1, R any](f F) func(context.Context, T0, T1) (R, error) { + return G.Uneitherize2[ReaderIOEither[R], func(context.Context, T0, T1) (R, error)](f) +} + // SequenceT2 converts 2 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple2]. func SequenceT2[T1, T2 any](t1 ReaderIOEither[T1], t2 ReaderIOEither[T2]) ReaderIOEither[T.Tuple2[T1, T2]] { return G.SequenceT2[ReaderIOEither[T.Tuple2[T1, T2]]](t1, t2) @@ -125,6 +143,12 @@ func Eitherize3[F ~func(context.Context, T0, T1, T2) (R, error), T0, T1, T2, R a return G.Eitherize3[ReaderIOEither[R]](f) } +// Uneitherize3 converts a function with 4 parameters returning a [ReaderIOEither[R]] into a function with 3 parameters returning a tuple. +// The first parameter is considered to be the [context.Context]. +func Uneitherize3[F ~func(T0, T1, T2) ReaderIOEither[R], T0, T1, T2, R any](f F) func(context.Context, T0, T1, T2) (R, error) { + return G.Uneitherize3[ReaderIOEither[R], func(context.Context, T0, T1, T2) (R, error)](f) +} + // SequenceT3 converts 3 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple3]. func SequenceT3[T1, T2, T3 any](t1 ReaderIOEither[T1], t2 ReaderIOEither[T2], t3 ReaderIOEither[T3]) ReaderIOEither[T.Tuple3[T1, T2, T3]] { return G.SequenceT3[ReaderIOEither[T.Tuple3[T1, T2, T3]]](t1, t2, t3) @@ -176,6 +200,12 @@ func Eitherize4[F ~func(context.Context, T0, T1, T2, T3) (R, error), T0, T1, T2, return G.Eitherize4[ReaderIOEither[R]](f) } +// Uneitherize4 converts a function with 5 parameters returning a [ReaderIOEither[R]] into a function with 4 parameters returning a tuple. +// The first parameter is considered to be the [context.Context]. +func Uneitherize4[F ~func(T0, T1, T2, T3) ReaderIOEither[R], T0, T1, T2, T3, R any](f F) func(context.Context, T0, T1, T2, T3) (R, error) { + return G.Uneitherize4[ReaderIOEither[R], func(context.Context, T0, T1, T2, T3) (R, error)](f) +} + // SequenceT4 converts 4 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple4]. func SequenceT4[T1, T2, T3, T4 any](t1 ReaderIOEither[T1], t2 ReaderIOEither[T2], t3 ReaderIOEither[T3], t4 ReaderIOEither[T4]) ReaderIOEither[T.Tuple4[T1, T2, T3, T4]] { return G.SequenceT4[ReaderIOEither[T.Tuple4[T1, T2, T3, T4]]](t1, t2, t3, t4) @@ -227,6 +257,12 @@ func Eitherize5[F ~func(context.Context, T0, T1, T2, T3, T4) (R, error), T0, T1, return G.Eitherize5[ReaderIOEither[R]](f) } +// Uneitherize5 converts a function with 6 parameters returning a [ReaderIOEither[R]] into a function with 5 parameters returning a tuple. +// The first parameter is considered to be the [context.Context]. +func Uneitherize5[F ~func(T0, T1, T2, T3, T4) ReaderIOEither[R], T0, T1, T2, T3, T4, R any](f F) func(context.Context, T0, T1, T2, T3, T4) (R, error) { + return G.Uneitherize5[ReaderIOEither[R], func(context.Context, T0, T1, T2, T3, T4) (R, error)](f) +} + // SequenceT5 converts 5 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple5]. func SequenceT5[T1, T2, T3, T4, T5 any](t1 ReaderIOEither[T1], t2 ReaderIOEither[T2], t3 ReaderIOEither[T3], t4 ReaderIOEither[T4], t5 ReaderIOEither[T5]) ReaderIOEither[T.Tuple5[T1, T2, T3, T4, T5]] { return G.SequenceT5[ReaderIOEither[T.Tuple5[T1, T2, T3, T4, T5]]](t1, t2, t3, t4, t5) @@ -278,6 +314,12 @@ func Eitherize6[F ~func(context.Context, T0, T1, T2, T3, T4, T5) (R, error), T0, return G.Eitherize6[ReaderIOEither[R]](f) } +// Uneitherize6 converts a function with 7 parameters returning a [ReaderIOEither[R]] into a function with 6 parameters returning a tuple. +// The first parameter is considered to be the [context.Context]. +func Uneitherize6[F ~func(T0, T1, T2, T3, T4, T5) ReaderIOEither[R], T0, T1, T2, T3, T4, T5, R any](f F) func(context.Context, T0, T1, T2, T3, T4, T5) (R, error) { + return G.Uneitherize6[ReaderIOEither[R], func(context.Context, T0, T1, T2, T3, T4, T5) (R, error)](f) +} + // SequenceT6 converts 6 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple6]. func SequenceT6[T1, T2, T3, T4, T5, T6 any](t1 ReaderIOEither[T1], t2 ReaderIOEither[T2], t3 ReaderIOEither[T3], t4 ReaderIOEither[T4], t5 ReaderIOEither[T5], t6 ReaderIOEither[T6]) ReaderIOEither[T.Tuple6[T1, T2, T3, T4, T5, T6]] { return G.SequenceT6[ReaderIOEither[T.Tuple6[T1, T2, T3, T4, T5, T6]]](t1, t2, t3, t4, t5, t6) @@ -329,6 +371,12 @@ func Eitherize7[F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6) (R, error), return G.Eitherize7[ReaderIOEither[R]](f) } +// Uneitherize7 converts a function with 8 parameters returning a [ReaderIOEither[R]] into a function with 7 parameters returning a tuple. +// The first parameter is considered to be the [context.Context]. +func Uneitherize7[F ~func(T0, T1, T2, T3, T4, T5, T6) ReaderIOEither[R], T0, T1, T2, T3, T4, T5, T6, R any](f F) func(context.Context, T0, T1, T2, T3, T4, T5, T6) (R, error) { + return G.Uneitherize7[ReaderIOEither[R], func(context.Context, T0, T1, T2, T3, T4, T5, T6) (R, error)](f) +} + // SequenceT7 converts 7 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple7]. func SequenceT7[T1, T2, T3, T4, T5, T6, T7 any](t1 ReaderIOEither[T1], t2 ReaderIOEither[T2], t3 ReaderIOEither[T3], t4 ReaderIOEither[T4], t5 ReaderIOEither[T5], t6 ReaderIOEither[T6], t7 ReaderIOEither[T7]) ReaderIOEither[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]] { return G.SequenceT7[ReaderIOEither[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]]](t1, t2, t3, t4, t5, t6, t7) @@ -380,6 +428,12 @@ func Eitherize8[F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7) (R, err return G.Eitherize8[ReaderIOEither[R]](f) } +// Uneitherize8 converts a function with 9 parameters returning a [ReaderIOEither[R]] into a function with 8 parameters returning a tuple. +// The first parameter is considered to be the [context.Context]. +func Uneitherize8[F ~func(T0, T1, T2, T3, T4, T5, T6, T7) ReaderIOEither[R], T0, T1, T2, T3, T4, T5, T6, T7, R any](f F) func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7) (R, error) { + return G.Uneitherize8[ReaderIOEither[R], func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7) (R, error)](f) +} + // SequenceT8 converts 8 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple8]. func SequenceT8[T1, T2, T3, T4, T5, T6, T7, T8 any](t1 ReaderIOEither[T1], t2 ReaderIOEither[T2], t3 ReaderIOEither[T3], t4 ReaderIOEither[T4], t5 ReaderIOEither[T5], t6 ReaderIOEither[T6], t7 ReaderIOEither[T7], t8 ReaderIOEither[T8]) ReaderIOEither[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]] { return G.SequenceT8[ReaderIOEither[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]](t1, t2, t3, t4, t5, t6, t7, t8) @@ -431,6 +485,12 @@ func Eitherize9[F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8) (R, return G.Eitherize9[ReaderIOEither[R]](f) } +// Uneitherize9 converts a function with 10 parameters returning a [ReaderIOEither[R]] into a function with 9 parameters returning a tuple. +// The first parameter is considered to be the [context.Context]. +func Uneitherize9[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8) ReaderIOEither[R], T0, T1, T2, T3, T4, T5, T6, T7, T8, R any](f F) func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8) (R, error) { + return G.Uneitherize9[ReaderIOEither[R], func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8) (R, error)](f) +} + // SequenceT9 converts 9 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple9]. func SequenceT9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t1 ReaderIOEither[T1], t2 ReaderIOEither[T2], t3 ReaderIOEither[T3], t4 ReaderIOEither[T4], t5 ReaderIOEither[T5], t6 ReaderIOEither[T6], t7 ReaderIOEither[T7], t8 ReaderIOEither[T8], t9 ReaderIOEither[T9]) ReaderIOEither[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]] { return G.SequenceT9[ReaderIOEither[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]](t1, t2, t3, t4, t5, t6, t7, t8, t9) @@ -482,6 +542,12 @@ func Eitherize10[F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 return G.Eitherize10[ReaderIOEither[R]](f) } +// Uneitherize10 converts a function with 11 parameters returning a [ReaderIOEither[R]] into a function with 10 parameters returning a tuple. +// The first parameter is considered to be the [context.Context]. +func Uneitherize10[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) ReaderIOEither[R], T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, R any](f F) func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (R, error) { + return G.Uneitherize10[ReaderIOEither[R], func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (R, error)](f) +} + // SequenceT10 converts 10 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple10]. func SequenceT10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t1 ReaderIOEither[T1], t2 ReaderIOEither[T2], t3 ReaderIOEither[T3], t4 ReaderIOEither[T4], t5 ReaderIOEither[T5], t6 ReaderIOEither[T6], t7 ReaderIOEither[T7], t8 ReaderIOEither[T8], t9 ReaderIOEither[T9], t10 ReaderIOEither[T10]) ReaderIOEither[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]] { return G.SequenceT10[ReaderIOEither[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]](t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) diff --git a/context/readerioeither/generic/gen.go b/context/readerioeither/generic/gen.go index 0da74be..6b16d8d 100644 --- a/context/readerioeither/generic/gen.go +++ b/context/readerioeither/generic/gen.go @@ -2,7 +2,7 @@ package generic // Code generated by go generate; DO NOT EDIT. // This file was generated by robots at -// 2024-02-29 16:18:46.1217523 +0100 CET m=+0.022262001 +// 2024-05-24 22:24:01.4250895 +0200 CEST m=+0.014515801 import ( "context" @@ -19,12 +19,28 @@ func Eitherize0[GRA ~func(context.Context) GIOA, F ~func(context.Context) (R, er return RE.Eitherize0[GRA](f) } +// Uneitherize0 converts a function with 0 parameters returning a [GRA] into a function with 0 parameters returning a tuple. +// The first parameter is considered to be the [context.Context]. +func Uneitherize0[GRA ~func(context.Context) GIOA, F ~func(context.Context) (R, error), GIOA ~func() E.Either[error, R], R any](f func() GRA) F { + return func(c context.Context) (R, error) { + return E.UnwrapError(f()(c)()) + } +} + // Eitherize1 converts a function with 1 parameters returning a tuple into a function with 1 parameters returning a [GRA] // The inverse function is [Uneitherize1] func Eitherize1[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0) (R, error), GIOA ~func() E.Either[error, R], T0, R any](f F) func(T0) GRA { return RE.Eitherize1[GRA](f) } +// Uneitherize1 converts a function with 1 parameters returning a [GRA] into a function with 1 parameters returning a tuple. +// The first parameter is considered to be the [context.Context]. +func Uneitherize1[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0) (R, error), GIOA ~func() E.Either[error, R], T0, R any](f func(T0) GRA) F { + return func(c context.Context, t0 T0) (R, error) { + return E.UnwrapError(f(t0)(c)()) + } +} + // SequenceT1 converts 1 readers into a reader of a [T.Tuple1]. func SequenceT1[ GR_TUPLE1 ~func(context.Context) GIO_TUPLE1, @@ -169,6 +185,14 @@ func Eitherize2[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1 return RE.Eitherize2[GRA](f) } +// Uneitherize2 converts a function with 2 parameters returning a [GRA] into a function with 2 parameters returning a tuple. +// The first parameter is considered to be the [context.Context]. +func Uneitherize2[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1) (R, error), GIOA ~func() E.Either[error, R], T0, T1, R any](f func(T0, T1) GRA) F { + return func(c context.Context, t0 T0, t1 T1) (R, error) { + return E.UnwrapError(f(t0, t1)(c)()) + } +} + // SequenceT2 converts 2 readers into a reader of a [T.Tuple2]. func SequenceT2[ GR_TUPLE2 ~func(context.Context) GIO_TUPLE2, @@ -364,6 +388,14 @@ func Eitherize3[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1 return RE.Eitherize3[GRA](f) } +// Uneitherize3 converts a function with 3 parameters returning a [GRA] into a function with 3 parameters returning a tuple. +// The first parameter is considered to be the [context.Context]. +func Uneitherize3[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1, T2) (R, error), GIOA ~func() E.Either[error, R], T0, T1, T2, R any](f func(T0, T1, T2) GRA) F { + return func(c context.Context, t0 T0, t1 T1, t2 T2) (R, error) { + return E.UnwrapError(f(t0, t1, t2)(c)()) + } +} + // SequenceT3 converts 3 readers into a reader of a [T.Tuple3]. func SequenceT3[ GR_TUPLE3 ~func(context.Context) GIO_TUPLE3, @@ -610,6 +642,14 @@ func Eitherize4[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1 return RE.Eitherize4[GRA](f) } +// Uneitherize4 converts a function with 4 parameters returning a [GRA] into a function with 4 parameters returning a tuple. +// The first parameter is considered to be the [context.Context]. +func Uneitherize4[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1, T2, T3) (R, error), GIOA ~func() E.Either[error, R], T0, T1, T2, T3, R any](f func(T0, T1, T2, T3) GRA) F { + return func(c context.Context, t0 T0, t1 T1, t2 T2, t3 T3) (R, error) { + return E.UnwrapError(f(t0, t1, t2, t3)(c)()) + } +} + // SequenceT4 converts 4 readers into a reader of a [T.Tuple4]. func SequenceT4[ GR_TUPLE4 ~func(context.Context) GIO_TUPLE4, @@ -907,6 +947,14 @@ func Eitherize5[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1 return RE.Eitherize5[GRA](f) } +// Uneitherize5 converts a function with 5 parameters returning a [GRA] into a function with 5 parameters returning a tuple. +// The first parameter is considered to be the [context.Context]. +func Uneitherize5[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1, T2, T3, T4) (R, error), GIOA ~func() E.Either[error, R], T0, T1, T2, T3, T4, R any](f func(T0, T1, T2, T3, T4) GRA) F { + return func(c context.Context, t0 T0, t1 T1, t2 T2, t3 T3, t4 T4) (R, error) { + return E.UnwrapError(f(t0, t1, t2, t3, t4)(c)()) + } +} + // SequenceT5 converts 5 readers into a reader of a [T.Tuple5]. func SequenceT5[ GR_TUPLE5 ~func(context.Context) GIO_TUPLE5, @@ -1255,6 +1303,14 @@ func Eitherize6[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1 return RE.Eitherize6[GRA](f) } +// Uneitherize6 converts a function with 6 parameters returning a [GRA] into a function with 6 parameters returning a tuple. +// The first parameter is considered to be the [context.Context]. +func Uneitherize6[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1, T2, T3, T4, T5) (R, error), GIOA ~func() E.Either[error, R], T0, T1, T2, T3, T4, T5, R any](f func(T0, T1, T2, T3, T4, T5) GRA) F { + return func(c context.Context, t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5) (R, error) { + return E.UnwrapError(f(t0, t1, t2, t3, t4, t5)(c)()) + } +} + // SequenceT6 converts 6 readers into a reader of a [T.Tuple6]. func SequenceT6[ GR_TUPLE6 ~func(context.Context) GIO_TUPLE6, @@ -1654,6 +1710,14 @@ func Eitherize7[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1 return RE.Eitherize7[GRA](f) } +// Uneitherize7 converts a function with 7 parameters returning a [GRA] into a function with 7 parameters returning a tuple. +// The first parameter is considered to be the [context.Context]. +func Uneitherize7[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6) (R, error), GIOA ~func() E.Either[error, R], T0, T1, T2, T3, T4, T5, T6, R any](f func(T0, T1, T2, T3, T4, T5, T6) GRA) F { + return func(c context.Context, t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6) (R, error) { + return E.UnwrapError(f(t0, t1, t2, t3, t4, t5, t6)(c)()) + } +} + // SequenceT7 converts 7 readers into a reader of a [T.Tuple7]. func SequenceT7[ GR_TUPLE7 ~func(context.Context) GIO_TUPLE7, @@ -2104,6 +2168,14 @@ func Eitherize8[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1 return RE.Eitherize8[GRA](f) } +// Uneitherize8 converts a function with 8 parameters returning a [GRA] into a function with 8 parameters returning a tuple. +// The first parameter is considered to be the [context.Context]. +func Uneitherize8[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7) (R, error), GIOA ~func() E.Either[error, R], T0, T1, T2, T3, T4, T5, T6, T7, R any](f func(T0, T1, T2, T3, T4, T5, T6, T7) GRA) F { + return func(c context.Context, t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7) (R, error) { + return E.UnwrapError(f(t0, t1, t2, t3, t4, t5, t6, t7)(c)()) + } +} + // SequenceT8 converts 8 readers into a reader of a [T.Tuple8]. func SequenceT8[ GR_TUPLE8 ~func(context.Context) GIO_TUPLE8, @@ -2605,6 +2677,14 @@ func Eitherize9[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1 return RE.Eitherize9[GRA](f) } +// Uneitherize9 converts a function with 9 parameters returning a [GRA] into a function with 9 parameters returning a tuple. +// The first parameter is considered to be the [context.Context]. +func Uneitherize9[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8) (R, error), GIOA ~func() E.Either[error, R], T0, T1, T2, T3, T4, T5, T6, T7, T8, R any](f func(T0, T1, T2, T3, T4, T5, T6, T7, T8) GRA) F { + return func(c context.Context, t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8) (R, error) { + return E.UnwrapError(f(t0, t1, t2, t3, t4, t5, t6, t7, t8)(c)()) + } +} + // SequenceT9 converts 9 readers into a reader of a [T.Tuple9]. func SequenceT9[ GR_TUPLE9 ~func(context.Context) GIO_TUPLE9, @@ -3157,6 +3237,14 @@ func Eitherize10[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T return RE.Eitherize10[GRA](f) } +// Uneitherize10 converts a function with 10 parameters returning a [GRA] into a function with 10 parameters returning a tuple. +// The first parameter is considered to be the [context.Context]. +func Uneitherize10[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (R, error), GIOA ~func() E.Either[error, R], T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, R any](f func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) GRA) F { + return func(c context.Context, t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9) (R, error) { + return E.UnwrapError(f(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9)(c)()) + } +} + // SequenceT10 converts 10 readers into a reader of a [T.Tuple10]. func SequenceT10[ GR_TUPLE10 ~func(context.Context) GIO_TUPLE10, diff --git a/internal/testing/sequence.go b/internal/testing/sequence.go new file mode 100644 index 0000000..de6ca0b --- /dev/null +++ b/internal/testing/sequence.go @@ -0,0 +1,64 @@ +// Copyright (c) 2023 IBM Corp. +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package testing + +import ( + "fmt" + "testing" + + EQ "github.com/IBM/fp-go/eq" + F "github.com/IBM/fp-go/function" + "github.com/IBM/fp-go/internal/functor" + "github.com/IBM/fp-go/internal/pointed" + "github.com/stretchr/testify/assert" +) + +// SequenceArrayTest tests if the sequence operation works in case the operation cannot error +func SequenceArrayTest[ + HKTA, + HKTB, + HKTAA any, // HKT[[]A] +]( + eq EQ.Eq[HKTB], + + pa pointed.Pointed[string, HKTA], + pb pointed.Pointed[bool, HKTB], + faa functor.Functor[[]string, bool, HKTAA, HKTB], + seq func([]HKTA) HKTAA, +) func(count int) func(t *testing.T) { + + return func(count int) func(t *testing.T) { + + exp := make([]string, count) + good := make([]HKTA, count) + for i := 0; i < count; i++ { + val := fmt.Sprintf("TestData %d", i) + exp[i] = val + good[i] = pa.Of(val) + } + + return func(t *testing.T) { + res := F.Pipe2( + good, + seq, + faa.Map(func(act []string) bool { + return assert.Equal(t, exp, act) + }), + ) + assert.True(t, eq.Equals(res, pb.Of(true))) + } + } +} diff --git a/io/eq.go b/io/eq.go index 255f908..dbd4d7e 100644 --- a/io/eq.go +++ b/io/eq.go @@ -24,3 +24,8 @@ import ( func Eq[A any](e EQ.Eq[A]) EQ.Eq[IO[A]] { return G.Eq[IO[A]](e) } + +// FromStrictEquals constructs an [EQ.Eq] from the canonical comparison function +func FromStrictEquals[A comparable]() EQ.Eq[IO[A]] { + return G.FromStrictEquals[IO[A]]() +} diff --git a/io/functor.go b/io/functor.go new file mode 100644 index 0000000..c21b6d2 --- /dev/null +++ b/io/functor.go @@ -0,0 +1,26 @@ +// Copyright (c) 2024 IBM Corp. +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package io + +import ( + "github.com/IBM/fp-go/internal/functor" + G "github.com/IBM/fp-go/io/generic" +) + +// Functor returns the monadic operations for [IO] +func Functor[A, B any]() functor.Functor[A, B, IO[A], IO[B]] { + return G.Functor[A, B, IO[A], IO[B]]() +} diff --git a/io/generic/eq.go b/io/generic/eq.go index 7fad19e..07b8e00 100644 --- a/io/generic/eq.go +++ b/io/generic/eq.go @@ -33,3 +33,8 @@ func Eq[GA ~func() A, A any](e EQ.Eq[A]) EQ.Eq[GA] { return eq(l, r)() }) } + +// FromStrictEquals constructs an [EQ.Eq] from the canonical comparison function +func FromStrictEquals[GA ~func() A, A comparable]() EQ.Eq[GA] { + return Eq[GA](EQ.FromStrictEquals[A]()) +} diff --git a/io/generic/functor.go b/io/generic/functor.go new file mode 100644 index 0000000..d265c95 --- /dev/null +++ b/io/generic/functor.go @@ -0,0 +1,31 @@ +// Copyright (c) 2024 IBM Corp. +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package generic + +import ( + "github.com/IBM/fp-go/internal/functor" +) + +type ioFunctor[A, B any, GA ~func() A, GB ~func() B] struct{} + +func (o *ioFunctor[A, B, GA, GB]) Map(f func(A) B) func(GA) GB { + return Map[GA, GB, A, B](f) +} + +// Functor implements the functoric operations for [IO] +func Functor[A, B any, GA ~func() A, GB ~func() B]() functor.Functor[A, B, GA, GB] { + return &ioFunctor[A, B, GA, GB]{} +} diff --git a/io/generic/pointed.go b/io/generic/pointed.go new file mode 100644 index 0000000..3202707 --- /dev/null +++ b/io/generic/pointed.go @@ -0,0 +1,31 @@ +// Copyright (c) 2024 IBM Corp. +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package generic + +import ( + "github.com/IBM/fp-go/internal/pointed" +) + +type ioPointed[A any, GA ~func() A] struct{} + +func (o *ioPointed[A, GA]) Of(a A) GA { + return Of[GA, A](a) +} + +// Pointed implements the pointedic operations for [IO] +func Pointed[A any, GA ~func() A]() pointed.Pointed[A, GA] { + return &ioPointed[A, GA]{} +} diff --git a/io/pointed.go b/io/pointed.go new file mode 100644 index 0000000..dab922e --- /dev/null +++ b/io/pointed.go @@ -0,0 +1,26 @@ +// Copyright (c) 2024 IBM Corp. +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package io + +import ( + "github.com/IBM/fp-go/internal/pointed" + G "github.com/IBM/fp-go/io/generic" +) + +// Pointed returns the monadic operations for [IO] +func Pointed[A any]() pointed.Pointed[A, IO[A]] { + return G.Pointed[A, IO[A]]() +} diff --git a/io/sequence_test.go b/io/sequence_test.go index 9f5133a..f670d62 100644 --- a/io/sequence_test.go +++ b/io/sequence_test.go @@ -16,8 +16,11 @@ package io import ( + "fmt" + A "github.com/IBM/fp-go/array" F "github.com/IBM/fp-go/function" + TST "github.com/IBM/fp-go/internal/testing" "github.com/stretchr/testify/assert" "testing" @@ -45,3 +48,18 @@ func TestMapSeq(t *testing.T) { assert.True(t, res()) } + +func TestSequenceArray(t *testing.T) { + + s := TST.SequenceArrayTest( + FromStrictEquals[bool](), + Pointed[string](), + Pointed[bool](), + Functor[[]string, bool](), + SequenceArray[string], + ) + + for i := 0; i < 10; i++ { + t.Run(fmt.Sprintf("TestSequenceArray %d", i), s(i)) + } +} diff --git a/option/array_test.go b/option/array_test.go index 2a31baa..0bc0d94 100644 --- a/option/array_test.go +++ b/option/array_test.go @@ -16,25 +16,13 @@ package option import ( + "fmt" "testing" - F "github.com/IBM/fp-go/function" + TST "github.com/IBM/fp-go/internal/testing" "github.com/stretchr/testify/assert" ) -func TestSequenceArray(t *testing.T) { - - one := Of(1) - two := Of(2) - - res := F.Pipe1( - []Option[int]{one, two}, - SequenceArray[int], - ) - - assert.Equal(t, res, Of([]int{1, 2})) -} - func TestCompactArray(t *testing.T) { ar := []Option[string]{ Of("ok"), @@ -45,3 +33,18 @@ func TestCompactArray(t *testing.T) { res := CompactArray(ar) assert.Equal(t, 2, len(res)) } + +func TestSequenceArray(t *testing.T) { + + s := TST.SequenceArrayTest( + FromStrictEquals[bool](), + Pointed[string](), + Pointed[bool](), + Functor[[]string, bool](), + SequenceArray[string], + ) + + for i := 0; i < 10; i++ { + t.Run(fmt.Sprintf("TestSequenceArray %d", i), s(i)) + } +} diff --git a/option/functor.go b/option/functor.go new file mode 100644 index 0000000..a9664a7 --- /dev/null +++ b/option/functor.go @@ -0,0 +1,31 @@ +// Copyright (c) 2024 IBM Corp. +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package option + +import ( + "github.com/IBM/fp-go/internal/functor" +) + +type optionFunctor[A, B any] struct{} + +func (o *optionFunctor[A, B]) Map(f func(A) B) func(Option[A]) Option[B] { + return Map[A, B](f) +} + +// Functor implements the functoric operations for [Option] +func Functor[A, B any]() functor.Functor[A, B, Option[A], Option[B]] { + return &optionFunctor[A, B]{} +} diff --git a/option/pointed.go b/option/pointed.go new file mode 100644 index 0000000..5b9047f --- /dev/null +++ b/option/pointed.go @@ -0,0 +1,31 @@ +// Copyright (c) 2024 IBM Corp. +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package option + +import ( + "github.com/IBM/fp-go/internal/pointed" +) + +type optionPointed[A any] struct{} + +func (o *optionPointed[A]) Of(a A) Option[A] { + return Of[A](a) +} + +// Pointed implements the Pointed operations for [Option] +func Pointed[A any]() pointed.Pointed[A, Option[A]] { + return &optionPointed[A]{} +}