1
0
mirror of https://github.com/IBM/fp-go.git synced 2025-08-10 22:31:32 +02:00

fix: add auto generation for Eitherize

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
This commit is contained in:
Dr. Carsten Leue
2023-07-13 16:14:38 +02:00
parent 288422ecf1
commit b34f3e3ae1
20 changed files with 2200 additions and 1270 deletions

13
cli/commands.go Normal file
View File

@@ -0,0 +1,13 @@
package cli
import (
C "github.com/urfave/cli/v2"
)
func Commands() []*C.Command {
return []*C.Command{
PipeCommand(),
OptionCommand(),
EitherCommand(),
}
}

24
cli/common.go Normal file
View File

@@ -0,0 +1,24 @@
package cli
import (
C "github.com/urfave/cli/v2"
)
const (
keyFilename = "filename"
keyCount = "count"
)
var (
flagFilename = &C.StringFlag{
Name: keyFilename,
Value: "gen.go",
Usage: "Name of the generated file",
}
flagCount = &C.IntFlag{
Name: keyCount,
Value: 20,
Usage: "Number of variations to create",
}
)

156
cli/either.go Normal file
View File

@@ -0,0 +1,156 @@
package cli
import (
"fmt"
"log"
"os"
"path/filepath"
"time"
C "github.com/urfave/cli/v2"
)
func generateUneitherize(f *os.File, i int) {
// Create the optionize version
fmt.Fprintf(f, "\n// Uneitherize%d converts a function with %d parameters returning an Either into a function with %d parameters returning a tuple\n", i, i, 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, ") Either[error, R]")
for j := 0; j < i; j++ {
fmt.Fprintf(f, ", T%d", j)
}
fmt.Fprintf(f, ", R any](f F) func(")
for j := 0; j < i; j++ {
if j > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "T%d", j)
}
fmt.Fprintf(f, ") (R, error) {\n")
fmt.Fprintf(f, " return func(")
for j := 0; j < i; j++ {
if j > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "t%d T%d", j, j)
}
fmt.Fprintf(f, ") (R, error) {\n")
fmt.Fprintf(f, " return UnwrapError(f(")
for j := 0; j < i; j++ {
if j > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "t%d", j)
}
fmt.Fprintln(f, "))")
fmt.Fprintln(f, " }")
fmt.Fprintln(f, "}")
}
func generateEitherize(f *os.File, i int) {
// Create the optionize version
fmt.Fprintf(f, "\n// Eitherize%d converts a function with %d parameters returning a tuple into a function with %d parameters returning an Either\n", i, i, i)
fmt.Fprintf(f, "func Eitherize%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, ") (R, error)")
for j := 0; j < i; j++ {
fmt.Fprintf(f, ", T%d", j)
}
fmt.Fprintf(f, ", R any](f F) func(")
for j := 0; j < i; j++ {
if j > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "T%d", j)
}
fmt.Fprintf(f, ") Either[error, R] {\n")
fmt.Fprintf(f, " return func(")
for j := 0; j < i; j++ {
if j > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "t%d T%d", j, j)
}
fmt.Fprintf(f, ") Either[error, R] {\n")
fmt.Fprintf(f, " return TryCatchError(func() (R, error) {\n")
fmt.Fprintf(f, " return f(")
for j := 0; j < i; j++ {
if j > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "t%d", j)
}
fmt.Fprintln(f, ")")
fmt.Fprintln(f, " })")
fmt.Fprintln(f, " }")
fmt.Fprintln(f, "}")
}
func generateEitherHelpers(filename string, count int) error {
dir, err := os.Getwd()
if err != nil {
return err
}
absDir, err := filepath.Abs(dir)
if err != nil {
return err
}
pkg := filepath.Base(absDir)
f, err := os.Create(filename)
if err != nil {
return err
}
defer f.Close()
// log
log.Printf("Generating code in [%s] for package [%s] with [%d] repetitions ...", filename, pkg, count)
// some header
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
fmt.Fprintln(f, "// This file was generated by robots at")
fmt.Fprintf(f, "// %s\n", time.Now())
fmt.Fprintf(f, "package %s\n\n", pkg)
// zero level functions
// optionize
generateEitherize(f, 0)
// unoptionize
generateUneitherize(f, 0)
for i := 1; i <= count; i++ {
// optionize
generateEitherize(f, i)
// unoptionize
generateUneitherize(f, i)
}
return nil
}
func EitherCommand() *C.Command {
return &C.Command{
Name: "either",
Usage: "generate code for Either",
Flags: []C.Flag{
flagCount,
flagFilename,
},
Action: func(ctx *C.Context) error {
return generateEitherHelpers(
ctx.String(keyFilename),
ctx.Int(keyCount),
)
},
}
}

166
cli/option.go Normal file
View File

@@ -0,0 +1,166 @@
package cli
import (
"fmt"
"log"
"os"
"path/filepath"
"time"
C "github.com/urfave/cli/v2"
)
func generateOptionize(f *os.File, i int) {
// Create the optionize version
fmt.Fprintf(f, "\n// Optionize%d converts a function with %d parameters returning a tuple of a return value R and a boolean into a function with %d parameters returning an Option[R]\n", i, i, i)
fmt.Fprintf(f, "func Optionize%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, ") (R, bool)")
for j := 0; j < i; j++ {
fmt.Fprintf(f, ", T%d", j)
}
fmt.Fprintf(f, ", R any](f F) func(")
for j := 0; j < i; j++ {
if j > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "T%d", j)
}
fmt.Fprintf(f, ") Option[R] {\n")
fmt.Fprintf(f, " return func(")
for j := 0; j < i; j++ {
if j > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "t%d T%d", j, j)
}
fmt.Fprintf(f, ") Option[R] {\n")
fmt.Fprintf(f, " return optionize(func() (R, bool) {\n")
fmt.Fprintf(f, " return f(")
for j := 0; j < i; j++ {
if j > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "t%d", j)
}
fmt.Fprintln(f, ")")
fmt.Fprintln(f, " })")
fmt.Fprintln(f, " }")
fmt.Fprintln(f, "}")
}
func generateUnoptionize(f *os.File, i int) {
// Create the optionize version
fmt.Fprintf(f, "\n// Unoptionize%d converts a function with %d parameters returning a tuple of a return value R and a boolean into a function with %d parameters returning an Option[R]\n", i, i, i)
fmt.Fprintf(f, "func Unoptionize%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, ") Option[R]")
for j := 0; j < i; j++ {
fmt.Fprintf(f, ", T%d", j)
}
fmt.Fprintf(f, ", R any](f F) func(")
for j := 0; j < i; j++ {
if j > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "T%d", j)
}
fmt.Fprintf(f, ") (R, bool) {\n")
fmt.Fprintf(f, " return func(")
for j := 0; j < i; j++ {
if j > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "t%d T%d", j, j)
}
fmt.Fprintf(f, ") (R, bool) {\n")
fmt.Fprintf(f, " return Unwrap(f(")
for j := 0; j < i; j++ {
if j > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "t%d", j)
}
fmt.Fprintln(f, "))")
fmt.Fprintln(f, " }")
fmt.Fprintln(f, "}")
}
func generateOptionHelpers(filename string, count int) error {
dir, err := os.Getwd()
if err != nil {
return err
}
absDir, err := filepath.Abs(dir)
if err != nil {
return err
}
pkg := filepath.Base(absDir)
f, err := os.Create(filename)
if err != nil {
return err
}
defer f.Close()
// log
log.Printf("Generating code in [%s] for package [%s] with [%d] repetitions ...", filename, pkg, count)
// some header
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
fmt.Fprintln(f, "// This file was generated by robots at")
fmt.Fprintf(f, "// %s\n", time.Now())
fmt.Fprintf(f, "package %s\n\n", pkg)
// print out some helpers
fmt.Fprintf(f, `// optionize converts a nullary function to an option
func optionize[R any](f func() (R, bool)) Option[R] {
if r, ok := f(); ok {
return Some(r)
}
return None[R]()
}
`)
// zero level functions
// optionize
generateOptionize(f, 0)
// unoptionize
generateUnoptionize(f, 0)
for i := 1; i <= count; i++ {
// optionize
generateOptionize(f, i)
// unoptionize
generateUnoptionize(f, i)
}
return nil
}
func OptionCommand() *C.Command {
return &C.Command{
Name: "option",
Usage: "generate code for Option",
Flags: []C.Flag{
flagCount,
flagFilename,
},
Action: func(ctx *C.Context) error {
return generateOptionHelpers(
ctx.String(keyFilename),
ctx.Int(keyCount),
)
},
}
}

View File

@@ -10,23 +10,141 @@ import (
C "github.com/urfave/cli/v2"
)
const (
keyCount = "count"
)
func generateNullary(f *os.File, i int) {
func generateVariadic(f *os.File, i int) {
// Create the nullary version
fmt.Fprintf(f, "\n// Nullary%d creates a parameter less function from a parameter less function and %d functions. When executed the first parameter less function gets executed and then the result is piped through the remaining functions\n", i, i-1)
fmt.Fprintf(f, "func Nullary%d[", i)
fmt.Fprintf(f, "\n// Variadic%d converts a function taking %d parameters and a final slice into a function with %d parameters but a final variadic argument\n", i, i, i)
fmt.Fprintf(f, "func Variadic%d[", i)
for j := 1; j <= i; j++ {
if j > 1 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "T%d", j)
}
fmt.Fprintf(f, " any](f1 func() T1")
if i > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "V, R any](f func(")
for j := 1; j <= i; j++ {
if j > 1 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "T%d", j)
}
if i > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "[]V) R) func(")
for j := 1; j <= i; j++ {
if j > 1 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "T%d", j)
}
if i > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "...V) R {\n")
fmt.Fprintf(f, " return func(")
for j := 1; j <= i; j++ {
if j > 1 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "t%d T%d", j, j)
}
if i > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "v ...V) R {\n")
fmt.Fprintf(f, " return f(")
for j := 1; j <= i; j++ {
if j > 1 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "t%d", j)
}
if i > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "v)\n")
fmt.Fprintf(f, " }\n")
fmt.Fprintf(f, "}")
}
func generateUnvariadic(f *os.File, i int) {
// Create the nullary version
fmt.Fprintf(f, "\n// Unvariadic%d converts a function taking %d parameters and a final variadic argument into a function with %d parameters but a final slice argument\n", i, i, i)
fmt.Fprintf(f, "func Unvariadic%d[", i)
for j := 1; j <= i; j++ {
if j > 1 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "T%d", j)
}
if i > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "V, R any](f func(")
for j := 1; j <= i; j++ {
if j > 1 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "T%d", j)
}
if i > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "...V) R) func(")
for j := 1; j <= i; j++ {
if j > 1 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "T%d", j)
}
if i > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "[]V) R {\n")
fmt.Fprintf(f, " return func(")
for j := 1; j <= i; j++ {
if j > 1 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "t%d T%d", j, j)
}
if i > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "v []V) R {\n")
fmt.Fprintf(f, " return f(")
for j := 1; j <= i; j++ {
if j > 1 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "t%d", j)
}
if i > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "v...)\n")
fmt.Fprintf(f, " }\n")
fmt.Fprintf(f, "}")
}
func generateNullary(f *os.File, i int) {
// Create the nullary version
fmt.Fprintf(f, "\n// Nullary%d creates a parameter less function from a parameter less function and %d functions. When executed the first parameter less function gets executed and then the result is piped through the remaining functions\n", i, i-1)
fmt.Fprintf(f, "func Nullary%d[F1 ~func() T1", i)
for j := 2; j <= i; j++ {
fmt.Fprintf(f, ", f%d func(T%d) T%d", j, j-1, j)
fmt.Fprintf(f, ", F%d ~func(T%d) T%d", j, j-1, j)
}
for j := 1; j <= i; j++ {
fmt.Fprintf(f, ", T%d", j)
}
fmt.Fprintf(f, " any](f1 F1")
for j := 2; j <= i; j++ {
fmt.Fprintf(f, ", f%d F%d", j, j)
}
fmt.Fprintf(f, ") func() T%d {\n", i)
fmt.Fprintf(f, " return func() T%d {\n", i)
@@ -42,9 +160,15 @@ func generateNullary(f *os.File, i int) {
func generateFlow(f *os.File, i int) {
// Create the flow version
fmt.Fprintf(f, "\n// Flow%d creates a function that takes an initial value t0 and sucessively applies %d functions where the input of a function is the return value of the previous function\n// The final return value is the result of the last function application\n", i, i)
fmt.Fprintf(f, "func Flow%d[T0", i)
fmt.Fprintf(f, "\n// Flow%d creates a function that takes an initial value t0 and successively applies %d functions where the input of a function is the return value of the previous function\n// The final return value is the result of the last function application\n", i, i)
fmt.Fprintf(f, "func Flow%d[", i)
for j := 1; j <= i; j++ {
if j > 1 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "F%d ~func(T%d) T%d", j, j-1, j)
}
for j := 0; j <= i; j++ {
fmt.Fprintf(f, ", T%d", j)
}
fmt.Fprintf(f, " any](")
@@ -52,7 +176,7 @@ func generateFlow(f *os.File, i int) {
if j > 1 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "f%d func(T%d) T%d", j, j-1, j)
fmt.Fprintf(f, "f%d F%d", j, j)
}
fmt.Fprintf(f, ") func(T0) T%d {\n", i)
fmt.Fprintf(f, " return func(t0 T0) T%d {\n", i)
@@ -69,14 +193,27 @@ func generateFlow(f *os.File, i int) {
func generatePipe(f *os.File, i int) {
// Create the pipe version
fmt.Fprintf(f, "\n// Pipe%d takes an initial value t0 and sucessively applies %d functions where the input of a function is the return value of the previous function\n// The final return value is the result of the last function application\n", i, i)
fmt.Fprintf(f, "func Pipe%d[T0", i)
fmt.Fprintf(f, "\n// Pipe%d takes an initial value t0 and successively applies %d functions where the input of a function is the return value of the previous function\n// The final return value is the result of the last function application\n", i, i)
fmt.Fprintf(f, "func Pipe%d[", i)
for j := 1; j <= i; j++ {
fmt.Fprintf(f, ", T%d", j)
if j > 1 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "F%d ~func(T%d) T%d", j, j-1, j)
}
if i > 0 {
fmt.Fprintf(f, ", ")
}
for j := 0; j <= i; j++ {
if j > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "T%d", j)
}
fmt.Fprintf(f, " any](t0 T0")
for j := 1; j <= i; j++ {
fmt.Fprintf(f, ", f%d func(T%d) T%d", j, j-1, j)
fmt.Fprintf(f, ", f%d F%d", j, j)
}
fmt.Fprintf(f, ") T%d {\n", i)
for j := 1; j <= i; j++ {
@@ -164,7 +301,7 @@ func generateUncurry(f *os.File, i int) {
fmt.Fprintf(f, "}\n")
}
func generateHelpers(count int) error {
func generatePipeHelpers(filename string, count int) error {
dir, err := os.Getwd()
if err != nil {
return err
@@ -174,13 +311,13 @@ func generateHelpers(count int) error {
return err
}
pkg := filepath.Base(absDir)
f, err := os.Create("gen.go")
f, err := os.Create(filename)
if err != nil {
return err
}
defer f.Close()
// log
log.Printf("Generating code for package [%s] with [%d] repetitions ...", pkg, count)
log.Printf("Generating code in [%s] for package [%s] with [%d] repetitions ...", filename, pkg, count)
// some header
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
@@ -189,6 +326,13 @@ func generateHelpers(count int) error {
fmt.Fprintf(f, "package %s\n", pkg)
// pipe
generatePipe(f, 0)
// variadic
generateVariadic(f, 0)
// unvariadic
generateUnvariadic(f, 0)
for i := 1; i <= count; i++ {
// pipe
@@ -201,6 +345,10 @@ func generateHelpers(count int) error {
generateCurry(f, i)
// uncurry
generateUncurry(f, i)
// variadic
generateVariadic(f, i)
// unvariadic
generateUnvariadic(f, i)
}
return nil
@@ -208,16 +356,18 @@ func generateHelpers(count int) error {
func PipeCommand() *C.Command {
return &C.Command{
Name: "pipe",
Name: "pipe",
Usage: "generate code for pipe, flow, curry, etc",
Description: "Code generation for pipe, flow, curry, etc",
Flags: []C.Flag{
&C.IntFlag{
Name: keyCount,
Value: 20,
Usage: "Number of variations to create",
},
flagCount,
flagFilename,
},
Action: func(ctx *C.Context) error {
return generateHelpers(ctx.Int(keyCount))
return generatePipeHelpers(
ctx.String(keyFilename),
ctx.Int(keyCount),
)
},
}
}

View File

@@ -52,6 +52,7 @@ func MonadFold[E, A, B any](ma Either[E, A], onLeft func(e E) B, onRight func(a
return onRight(ma.right)
}
// Unwrap converts an Either into the idiomatic tuple
func Unwrap[E, A any](ma Either[E, A]) (A, E) {
return ma.right, ma.left
}

3
either/doc.go Normal file
View File

@@ -0,0 +1,3 @@
package either
//go:generate go run .. either --count 10 --filename eitherize.go

View File

@@ -102,7 +102,7 @@ func Flatten[E, A any](mma Either[E, Either[E, A]]) Either[E, A] {
return MonadChain(mma, F.Identity[Either[E, A]])
}
func TryCatch[E, A any](f func() (A, error), onThrow func(error) E) Either[E, A] {
func TryCatch[FA ~func() (A, error), FE func(error) E, E, A any](f FA, onThrow FE) Either[E, A] {
val, err := f()
if err != nil {
return F.Pipe2(err, onThrow, Left[E, A])
@@ -110,14 +110,10 @@ func TryCatch[E, A any](f func() (A, error), onThrow func(error) E) Either[E, A]
return F.Pipe1(val, Right[E, A])
}
func TryCatchErrorG[GA ~func() (A, error), A any](f GA) Either[error, A] {
func TryCatchError[F ~func() (A, error), A any](f F) Either[error, A] {
return TryCatch(f, E.IdentityError)
}
func TryCatchError[A any](f func() (A, error)) Either[error, A] {
return TryCatchErrorG(f)
}
func Sequence2[E, T1, T2, R any](f func(T1, T2) Either[E, R]) func(Either[E, T1], Either[E, T2]) Either[E, R] {
return func(e1 Either[E, T1], e2 Either[E, T2]) Either[E, R] {
return MonadSequence2(e1, e2, f)
@@ -150,118 +146,13 @@ func ToError[A any](e Either[error, A]) error {
return MonadFold(e, E.IdentityError, F.Constant1[A, error](nil))
}
func Eitherize0G[GA ~func() (R, error), GB ~func() Either[error, R], R any](f GA) GB {
return F.Bind1(TryCatchErrorG[GA, R], f)
}
func Eitherize0[R any](f func() (R, error)) func() Either[error, R] {
return Eitherize0G[func() (R, error), func() Either[error, R]](f)
}
func Uneitherize0G[GA ~func() Either[error, R], GB ~func() (R, error), R any](f GA) GB {
return func() (R, error) {
return UnwrapError(f())
}
}
func Uneitherize0[R any](f func() Either[error, R]) func() (R, error) {
return Uneitherize0G[func() Either[error, R], func() (R, error)](f)
}
func Eitherize1G[GA ~func(T1) (R, error), GB ~func(T1) Either[error, R], T1, R any](f GA) GB {
return func(t1 T1) Either[error, R] {
return TryCatchError(func() (R, error) {
return f(t1)
})
}
}
func Eitherize1[T1, R any](f func(T1) (R, error)) func(T1) Either[error, R] {
return Eitherize1G[func(T1) (R, error), func(T1) Either[error, R]](f)
}
func Uneitherize1G[GA ~func(T1) Either[error, R], GB ~func(T1) (R, error), T1, R any](f GA) GB {
return func(t1 T1) (R, error) {
return UnwrapError(f(t1))
}
}
func Uneitherize1[T1, R any](f func(T1) Either[error, R]) func(T1) (R, error) {
return Uneitherize1G[func(T1) Either[error, R], func(T1) (R, error)](f)
}
func Eitherize2G[GA ~func(t1 T1, t2 T2) (R, error), GB ~func(t1 T1, t2 T2) Either[error, R], T1, T2, R any](f GA) GB {
return func(t1 T1, t2 T2) Either[error, R] {
return TryCatchError(func() (R, error) {
return f(t1, t2)
})
}
}
func Eitherize2[T1, T2, R any](f func(t1 T1, t2 T2) (R, error)) func(t1 T1, t2 T2) Either[error, R] {
return Eitherize2G[func(t1 T1, t2 T2) (R, error), func(t1 T1, t2 T2) Either[error, R]](f)
}
func Uneitherize2G[GA ~func(T1, T2) Either[error, R], GB ~func(T1, T2) (R, error), T1, T2, R any](f GA) GB {
return func(t1 T1, t2 T2) (R, error) {
return UnwrapError(f(t1, t2))
}
}
func Uneitherize2[T1, T2, R any](f func(T1, T2) Either[error, R]) func(T1, T2) (R, error) {
return Uneitherize2G[func(T1, T2) Either[error, R], func(T1, T2) (R, error)](f)
}
func Eitherize3G[GA ~func(t1 T1, t2 T2, t3 T3) (R, error), GB ~func(t1 T1, t2 T2, t3 T3) Either[error, R], T1, T2, T3, R any](f GA) GB {
return func(t1 T1, t2 T2, t3 T3) Either[error, R] {
return TryCatchError(func() (R, error) {
return f(t1, t2, t3)
})
}
}
func Eitherize3[T1, T2, T3, R any](f func(t1 T1, t2 T2, t3 T3) (R, error)) func(t1 T1, t2 T2, t3 T3) Either[error, R] {
return Eitherize3G[func(t1 T1, t2 T2, t3 T3) (R, error), func(t1 T1, t2 T2, t3 T3) Either[error, R]](f)
}
func Uneitherize3G[GA ~func(T1, T2, T3) Either[error, R], GB ~func(T1, T2, T3) (R, error), T1, T2, T3, R any](f GA) GB {
return func(t1 T1, t2 T2, t3 T3) (R, error) {
return UnwrapError(f(t1, t2, t3))
}
}
func Uneitherize3[T1, T2, T3, R any](f func(T1, T2, T3) Either[error, R]) func(T1, T2, T3) (R, error) {
return Uneitherize3G[func(T1, T2, T3) Either[error, R], func(T1, T2, T3) (R, error)](f)
}
func Eitherize4G[GA ~func(t1 T1, t2 T2, t3 T3, t4 T4) (R, error), GB ~func(t1 T1, t2 T2, t3 T3, t4 T4) Either[error, R], T1, T2, T3, T4, R any](f GA) GB {
return func(t1 T1, t2 T2, t3 T3, t4 T4) Either[error, R] {
return TryCatchError(func() (R, error) {
return f(t1, t2, t3, t4)
})
}
}
func Eitherize4[T1, T2, T3, T4, R any](f func(t1 T1, t2 T2, t3 T3, t4 T4) (R, error)) func(t1 T1, t2 T2, t3 T3, t4 T4) Either[error, R] {
return Eitherize4G[func(t1 T1, t2 T2, t3 T3, t4 T4) (R, error), func(t1 T1, t2 T2, t3 T3, t4 T4) Either[error, R]](f)
}
func Uneitherize4G[GA ~func(T1, T2, T3, T4) Either[error, R], GB ~func(T1, T2, T3, T4) (R, error), T1, T2, T3, T4, R any](f GA) GB {
return func(t1 T1, t2 T2, t3 T3, t4 T4) (R, error) {
return UnwrapError(f(t1, t2, t3, t4))
}
}
func Uneitherize4[T1, T2, T3, T4, R any](f func(T1, T2, T3, T4) Either[error, R]) func(T1, T2, T3, T4) (R, error) {
return Uneitherize4G[func(T1, T2, T3, T4) Either[error, R], func(T1, T2, T3, T4) (R, error)](f)
}
func Fold[E, A, B any](onLeft func(E) B, onRight func(A) B) func(Either[E, A]) B {
return func(ma Either[E, A]) B {
return MonadFold(ma, onLeft, onRight)
}
}
// UnwrapError converts an Either into the idiomatic tuple
func UnwrapError[A any](ma Either[error, A]) (A, error) {
return Unwrap[error](ma)
}

180
either/eitherize.go Normal file
View File

@@ -0,0 +1,180 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-07-13 16:10:30.7402002 +0200 CEST m=+0.008416101
package either
// Eitherize0 converts a function with 0 parameters returning a tuple into a function with 0 parameters returning an Either
func Eitherize0[F ~func() (R, error), R any](f F) func() Either[error, R] {
return func() Either[error, R] {
return TryCatchError(func() (R, error) {
return f()
})
}
}
// Uneitherize0 converts a function with 0 parameters returning an Either into a function with 0 parameters returning a tuple
func Uneitherize0[F ~func() Either[error, R], R any](f F) func() (R, error) {
return func() (R, error) {
return UnwrapError(f())
}
}
// Eitherize1 converts a function with 1 parameters returning a tuple into a function with 1 parameters returning an Either
func Eitherize1[F ~func(T0) (R, error), T0, R any](f F) func(T0) Either[error, R] {
return func(t0 T0) Either[error, R] {
return TryCatchError(func() (R, error) {
return f(t0)
})
}
}
// Uneitherize1 converts a function with 1 parameters returning an Either into a function with 1 parameters returning a tuple
func Uneitherize1[F ~func(T0) Either[error, R], T0, R any](f F) func(T0) (R, error) {
return func(t0 T0) (R, error) {
return UnwrapError(f(t0))
}
}
// Eitherize2 converts a function with 2 parameters returning a tuple into a function with 2 parameters returning an Either
func Eitherize2[F ~func(T0, T1) (R, error), T0, T1, R any](f F) func(T0, T1) Either[error, R] {
return func(t0 T0, t1 T1) Either[error, R] {
return TryCatchError(func() (R, error) {
return f(t0, t1)
})
}
}
// Uneitherize2 converts a function with 2 parameters returning an Either into a function with 2 parameters returning a tuple
func Uneitherize2[F ~func(T0, T1) Either[error, R], T0, T1, R any](f F) func(T0, T1) (R, error) {
return func(t0 T0, t1 T1) (R, error) {
return UnwrapError(f(t0, t1))
}
}
// Eitherize3 converts a function with 3 parameters returning a tuple into a function with 3 parameters returning an Either
func Eitherize3[F ~func(T0, T1, T2) (R, error), T0, T1, T2, R any](f F) func(T0, T1, T2) Either[error, R] {
return func(t0 T0, t1 T1, t2 T2) Either[error, R] {
return TryCatchError(func() (R, error) {
return f(t0, t1, t2)
})
}
}
// Uneitherize3 converts a function with 3 parameters returning an Either into a function with 3 parameters returning a tuple
func Uneitherize3[F ~func(T0, T1, T2) Either[error, R], T0, T1, T2, R any](f F) func(T0, T1, T2) (R, error) {
return func(t0 T0, t1 T1, t2 T2) (R, error) {
return UnwrapError(f(t0, t1, t2))
}
}
// Eitherize4 converts a function with 4 parameters returning a tuple into a function with 4 parameters returning an Either
func Eitherize4[F ~func(T0, T1, T2, T3) (R, error), T0, T1, T2, T3, R any](f F) func(T0, T1, T2, T3) Either[error, R] {
return func(t0 T0, t1 T1, t2 T2, t3 T3) Either[error, R] {
return TryCatchError(func() (R, error) {
return f(t0, t1, t2, t3)
})
}
}
// Uneitherize4 converts a function with 4 parameters returning an Either into a function with 4 parameters returning a tuple
func Uneitherize4[F ~func(T0, T1, T2, T3) Either[error, R], T0, T1, T2, T3, R any](f F) func(T0, T1, T2, T3) (R, error) {
return func(t0 T0, t1 T1, t2 T2, t3 T3) (R, error) {
return UnwrapError(f(t0, t1, t2, t3))
}
}
// Eitherize5 converts a function with 5 parameters returning a tuple into a function with 5 parameters returning an Either
func Eitherize5[F ~func(T0, T1, T2, T3, T4) (R, error), T0, T1, T2, T3, T4, R any](f F) func(T0, T1, T2, T3, T4) Either[error, R] {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4) Either[error, R] {
return TryCatchError(func() (R, error) {
return f(t0, t1, t2, t3, t4)
})
}
}
// Uneitherize5 converts a function with 5 parameters returning an Either into a function with 5 parameters returning a tuple
func Uneitherize5[F ~func(T0, T1, T2, T3, T4) Either[error, R], T0, T1, T2, T3, T4, R any](f F) func(T0, T1, T2, T3, T4) (R, error) {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4) (R, error) {
return UnwrapError(f(t0, t1, t2, t3, t4))
}
}
// Eitherize6 converts a function with 6 parameters returning a tuple into a function with 6 parameters returning an Either
func Eitherize6[F ~func(T0, T1, T2, T3, T4, T5) (R, error), T0, T1, T2, T3, T4, T5, R any](f F) func(T0, T1, T2, T3, T4, T5) Either[error, R] {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5) Either[error, R] {
return TryCatchError(func() (R, error) {
return f(t0, t1, t2, t3, t4, t5)
})
}
}
// Uneitherize6 converts a function with 6 parameters returning an Either into a function with 6 parameters returning a tuple
func Uneitherize6[F ~func(T0, T1, T2, T3, T4, T5) Either[error, R], T0, T1, T2, T3, T4, T5, R any](f F) func(T0, T1, T2, T3, T4, T5) (R, error) {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5) (R, error) {
return UnwrapError(f(t0, t1, t2, t3, t4, t5))
}
}
// Eitherize7 converts a function with 7 parameters returning a tuple into a function with 7 parameters returning an Either
func Eitherize7[F ~func(T0, T1, T2, T3, T4, T5, T6) (R, error), T0, T1, T2, T3, T4, T5, T6, R any](f F) func(T0, T1, T2, T3, T4, T5, T6) Either[error, R] {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6) Either[error, R] {
return TryCatchError(func() (R, error) {
return f(t0, t1, t2, t3, t4, t5, t6)
})
}
}
// Uneitherize7 converts a function with 7 parameters returning an Either into a function with 7 parameters returning a tuple
func Uneitherize7[F ~func(T0, T1, T2, T3, T4, T5, T6) Either[error, R], T0, T1, T2, T3, T4, T5, T6, R any](f F) func(T0, T1, T2, T3, T4, T5, T6) (R, error) {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6) (R, error) {
return UnwrapError(f(t0, t1, t2, t3, t4, t5, t6))
}
}
// Eitherize8 converts a function with 8 parameters returning a tuple into a function with 8 parameters returning an Either
func Eitherize8[F ~func(T0, T1, T2, T3, T4, T5, T6, T7) (R, error), T0, T1, T2, T3, T4, T5, T6, T7, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7) Either[error, R] {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7) Either[error, R] {
return TryCatchError(func() (R, error) {
return f(t0, t1, t2, t3, t4, t5, t6, t7)
})
}
}
// Uneitherize8 converts a function with 8 parameters returning an Either into a function with 8 parameters returning a tuple
func Uneitherize8[F ~func(T0, T1, T2, T3, T4, T5, T6, T7) Either[error, R], T0, T1, T2, T3, T4, T5, T6, T7, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7) (R, error) {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7) (R, error) {
return UnwrapError(f(t0, t1, t2, t3, t4, t5, t6, t7))
}
}
// Eitherize9 converts a function with 9 parameters returning a tuple into a function with 9 parameters returning an Either
func Eitherize9[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8) (R, error), T0, T1, T2, T3, T4, T5, T6, T7, T8, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8) Either[error, R] {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8) Either[error, R] {
return TryCatchError(func() (R, error) {
return f(t0, t1, t2, t3, t4, t5, t6, t7, t8)
})
}
}
// Uneitherize9 converts a function with 9 parameters returning an Either into a function with 9 parameters returning a tuple
func Uneitherize9[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8) Either[error, R], T0, T1, T2, T3, T4, T5, T6, T7, T8, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8) (R, error) {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8) (R, error) {
return UnwrapError(f(t0, t1, t2, t3, t4, t5, t6, t7, t8))
}
}
// Eitherize10 converts a function with 10 parameters returning a tuple into a function with 10 parameters returning an Either
func Eitherize10[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (R, error), T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) Either[error, R] {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9) Either[error, R] {
return TryCatchError(func() (R, error) {
return f(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9)
})
}
}
// Uneitherize10 converts a function with 10 parameters returning an Either into a function with 10 parameters returning a tuple
func Uneitherize10[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) Either[error, R], T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (R, error) {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9) (R, error) {
return UnwrapError(f(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9))
}
}

View File

@@ -1,3 +1,3 @@
package function
//go:generate go run .. pipe --count 20
//go:generate go run .. pipe --count 20 --filename gen.go

View File

@@ -1,9 +1,5 @@
package function
func Pipe0[T0 any](t0 T0) T0 {
return t0
}
// Identity returns the value 'a'
func Identity[A any](a A) A {
return a

File diff suppressed because it is too large Load Diff

View File

@@ -1,61 +0,0 @@
package function
func Variadic0[V, R any](f func([]V) R) func(...V) R {
return func(v ...V) R {
return f(v)
}
}
func Variadic1[T1, V, R any](f func(T1, []V) R) func(T1, ...V) R {
return func(t1 T1, v ...V) R {
return f(t1, v)
}
}
func Variadic2[T1, T2, V, R any](f func(T1, T2, []V) R) func(T1, T2, ...V) R {
return func(t1 T1, t2 T2, v ...V) R {
return f(t1, t2, v)
}
}
func Variadic3[T1, T2, T3, V, R any](f func(T1, T2, T3, []V) R) func(T1, T2, T3, ...V) R {
return func(t1 T1, t2 T2, t3 T3, v ...V) R {
return f(t1, t2, t3, v)
}
}
func Variadic4[T1, T2, T3, T4, V, R any](f func(T1, T2, T3, T4, []V) R) func(T1, T2, T3, T4, ...V) R {
return func(t1 T1, t2 T2, t3 T3, t4 T4, v ...V) R {
return f(t1, t2, t3, t4, v)
}
}
func Unvariadic0[V, R any](f func(...V) R) func([]V) R {
return func(v []V) R {
return f(v...)
}
}
func Unvariadic1[T1, V, R any](f func(T1, ...V) R) func(T1, []V) R {
return func(t1 T1, v []V) R {
return f(t1, v...)
}
}
func Unvariadic2[T1, T2, V, R any](f func(T1, T2, ...V) R) func(T1, T2, []V) R {
return func(t1 T1, t2 T2, v []V) R {
return f(t1, t2, v...)
}
}
func Unvariadic3[T1, T2, T3, V, R any](f func(T1, T2, T3, ...V) R) func(T1, T2, T3, []V) R {
return func(t1 T1, t2 T2, t3 T3, v []V) R {
return f(t1, t2, t3, v...)
}
}
func Unvariadic4[T1, T2, T3, T4, V, R any](f func(T1, T2, T3, T4, ...V) R) func(T1, T2, T3, T4, []V) R {
return func(t1 T1, t2 T2, t3 T3, t4 T4, v []V) R {
return f(t1, t2, t3, t4, v...)
}
}

7
go.mod
View File

@@ -2,15 +2,16 @@ module github.com/ibm/fp-go
go 1.20
require github.com/stretchr/testify v1.8.4
require (
github.com/stretchr/testify v1.8.4
github.com/urfave/cli/v2 v2.25.7
)
require (
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/stretchr/objx v0.5.0 // indirect
github.com/urfave/cli/v2 v2.25.7 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

9
go.sum
View File

@@ -1,25 +1,18 @@
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=
github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -12,11 +12,9 @@ import (
func main() {
app := &C.App{
Name: "fp-go",
Usage: "Code generation for fp-go",
Commands: []*C.Command{
cli.PipeCommand(),
},
Name: "fp-go",
Usage: "Code generation for fp-go",
Commands: cli.Commands(),
}
if err := app.Run(os.Args); err != nil {

View File

@@ -1 +1,3 @@
package option
//go:generate go run .. option --count 10 --filename optionize.go

View File

@@ -20,24 +20,8 @@ func FromNillable[A any](a *A) Option[*A] {
return fromPredicate(a, F.IsNonNil[A])
}
func fromValidation[A, B any](a A, f func(A) (B, bool)) Option[B] {
b, ok := f(a)
if ok {
return Some(b)
}
return None[B]()
}
func fromValidation0[A any](f func() (A, bool)) Option[A] {
a, ok := f()
if ok {
return Some(a)
}
return None[A]()
}
func FromValidation[A, B any](f func(A) (B, bool)) func(A) Option[B] {
return F.Bind2nd(fromValidation[A, B], f)
return Optionize1(f)
}
// MonadAp is the applicative functor of Option
@@ -141,65 +125,3 @@ func Reduce[A, B any](f func(B, A) B, initial B) func(Option[A]) B {
func Filter[A any](pred func(A) bool) func(Option[A]) Option[A] {
return Fold(None[A], F.Ternary(pred, Of[A], F.Ignore1[A](None[A])))
}
func Optionize0[R any](f func() (R, bool)) func() Option[R] {
return func() Option[R] {
return fromValidation0(f)
}
}
func Optionize1[T1, R any](f func(T1) (R, bool)) func(T1) Option[R] {
return func(t1 T1) Option[R] {
return fromValidation0(func() (R, bool) {
return f(t1)
})
}
}
func Unoptionize1[T1, R any](f func(T1) Option[R]) func(T1) (R, bool) {
return func(t1 T1) (R, bool) {
return Unwrap(f(t1))
}
}
func Optionize2[T1, T2, R any](f func(t1 T1, t2 T2) (R, bool)) func(t1 T1, t2 T2) Option[R] {
return func(t1 T1, t2 T2) Option[R] {
return fromValidation0(func() (R, bool) {
return f(t1, t2)
})
}
}
func Unoptionize2[T1, T2, R any](f func(T1, T2) Option[R]) func(T1, T2) (R, bool) {
return func(t1 T1, t2 T2) (R, bool) {
return Unwrap(f(t1, t2))
}
}
func Optionize3[T1, T2, T3, R any](f func(t1 T1, t2 T2, t3 T3) (R, bool)) func(t1 T1, t2 T2, t3 T3) Option[R] {
return func(t1 T1, t2 T2, t3 T3) Option[R] {
return fromValidation0(func() (R, bool) {
return f(t1, t2, t3)
})
}
}
func Unoptionize3[T1, T2, T3, R any](f func(T1, T2, T3) Option[R]) func(T1, T2, T3) (R, bool) {
return func(t1 T1, t2 T2, t3 T3) (R, bool) {
return Unwrap(f(t1, t2, t3))
}
}
func Optionize4[T1, T2, T3, T4, R any](f func(t1 T1, t2 T2, t3 T3, t4 T4) (R, bool)) func(t1 T1, t2 T2, t3 T3, t4 T4) Option[R] {
return func(t1 T1, t2 T2, t3 T3, t4 T4) Option[R] {
return fromValidation0(func() (R, bool) {
return f(t1, t2, t3, t4)
})
}
}
func Unoptionize4[T1, T2, T3, T4, R any](f func(T1, T2, T3, T4) Option[R]) func(T1, T2, T3, T4) (R, bool) {
return func(t1 T1, t2 T2, t3 T3, t4 T4) (R, bool) {
return Unwrap(f(t1, t2, t3, t4))
}
}

188
option/optionize.go Normal file
View File

@@ -0,0 +1,188 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-07-13 16:10:33.8303184 +0200 CEST m=+0.008901701
package option
// optionize converts a nullary function to an option
func optionize[R any](f func() (R, bool)) Option[R] {
if r, ok := f(); ok {
return Some(r)
}
return None[R]()
}
// Optionize0 converts a function with 0 parameters returning a tuple of a return value R and a boolean into a function with 0 parameters returning an Option[R]
func Optionize0[F ~func() (R, bool), R any](f F) func() Option[R] {
return func() Option[R] {
return optionize(func() (R, bool) {
return f()
})
}
}
// Unoptionize0 converts a function with 0 parameters returning a tuple of a return value R and a boolean into a function with 0 parameters returning an Option[R]
func Unoptionize0[F ~func() Option[R], R any](f F) func() (R, bool) {
return func() (R, bool) {
return Unwrap(f())
}
}
// Optionize1 converts a function with 1 parameters returning a tuple of a return value R and a boolean into a function with 1 parameters returning an Option[R]
func Optionize1[F ~func(T0) (R, bool), T0, R any](f F) func(T0) Option[R] {
return func(t0 T0) Option[R] {
return optionize(func() (R, bool) {
return f(t0)
})
}
}
// Unoptionize1 converts a function with 1 parameters returning a tuple of a return value R and a boolean into a function with 1 parameters returning an Option[R]
func Unoptionize1[F ~func(T0) Option[R], T0, R any](f F) func(T0) (R, bool) {
return func(t0 T0) (R, bool) {
return Unwrap(f(t0))
}
}
// Optionize2 converts a function with 2 parameters returning a tuple of a return value R and a boolean into a function with 2 parameters returning an Option[R]
func Optionize2[F ~func(T0, T1) (R, bool), T0, T1, R any](f F) func(T0, T1) Option[R] {
return func(t0 T0, t1 T1) Option[R] {
return optionize(func() (R, bool) {
return f(t0, t1)
})
}
}
// Unoptionize2 converts a function with 2 parameters returning a tuple of a return value R and a boolean into a function with 2 parameters returning an Option[R]
func Unoptionize2[F ~func(T0, T1) Option[R], T0, T1, R any](f F) func(T0, T1) (R, bool) {
return func(t0 T0, t1 T1) (R, bool) {
return Unwrap(f(t0, t1))
}
}
// Optionize3 converts a function with 3 parameters returning a tuple of a return value R and a boolean into a function with 3 parameters returning an Option[R]
func Optionize3[F ~func(T0, T1, T2) (R, bool), T0, T1, T2, R any](f F) func(T0, T1, T2) Option[R] {
return func(t0 T0, t1 T1, t2 T2) Option[R] {
return optionize(func() (R, bool) {
return f(t0, t1, t2)
})
}
}
// Unoptionize3 converts a function with 3 parameters returning a tuple of a return value R and a boolean into a function with 3 parameters returning an Option[R]
func Unoptionize3[F ~func(T0, T1, T2) Option[R], T0, T1, T2, R any](f F) func(T0, T1, T2) (R, bool) {
return func(t0 T0, t1 T1, t2 T2) (R, bool) {
return Unwrap(f(t0, t1, t2))
}
}
// Optionize4 converts a function with 4 parameters returning a tuple of a return value R and a boolean into a function with 4 parameters returning an Option[R]
func Optionize4[F ~func(T0, T1, T2, T3) (R, bool), T0, T1, T2, T3, R any](f F) func(T0, T1, T2, T3) Option[R] {
return func(t0 T0, t1 T1, t2 T2, t3 T3) Option[R] {
return optionize(func() (R, bool) {
return f(t0, t1, t2, t3)
})
}
}
// Unoptionize4 converts a function with 4 parameters returning a tuple of a return value R and a boolean into a function with 4 parameters returning an Option[R]
func Unoptionize4[F ~func(T0, T1, T2, T3) Option[R], T0, T1, T2, T3, R any](f F) func(T0, T1, T2, T3) (R, bool) {
return func(t0 T0, t1 T1, t2 T2, t3 T3) (R, bool) {
return Unwrap(f(t0, t1, t2, t3))
}
}
// Optionize5 converts a function with 5 parameters returning a tuple of a return value R and a boolean into a function with 5 parameters returning an Option[R]
func Optionize5[F ~func(T0, T1, T2, T3, T4) (R, bool), T0, T1, T2, T3, T4, R any](f F) func(T0, T1, T2, T3, T4) Option[R] {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4) Option[R] {
return optionize(func() (R, bool) {
return f(t0, t1, t2, t3, t4)
})
}
}
// Unoptionize5 converts a function with 5 parameters returning a tuple of a return value R and a boolean into a function with 5 parameters returning an Option[R]
func Unoptionize5[F ~func(T0, T1, T2, T3, T4) Option[R], T0, T1, T2, T3, T4, R any](f F) func(T0, T1, T2, T3, T4) (R, bool) {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4) (R, bool) {
return Unwrap(f(t0, t1, t2, t3, t4))
}
}
// Optionize6 converts a function with 6 parameters returning a tuple of a return value R and a boolean into a function with 6 parameters returning an Option[R]
func Optionize6[F ~func(T0, T1, T2, T3, T4, T5) (R, bool), T0, T1, T2, T3, T4, T5, R any](f F) func(T0, T1, T2, T3, T4, T5) Option[R] {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5) Option[R] {
return optionize(func() (R, bool) {
return f(t0, t1, t2, t3, t4, t5)
})
}
}
// Unoptionize6 converts a function with 6 parameters returning a tuple of a return value R and a boolean into a function with 6 parameters returning an Option[R]
func Unoptionize6[F ~func(T0, T1, T2, T3, T4, T5) Option[R], T0, T1, T2, T3, T4, T5, R any](f F) func(T0, T1, T2, T3, T4, T5) (R, bool) {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5) (R, bool) {
return Unwrap(f(t0, t1, t2, t3, t4, t5))
}
}
// Optionize7 converts a function with 7 parameters returning a tuple of a return value R and a boolean into a function with 7 parameters returning an Option[R]
func Optionize7[F ~func(T0, T1, T2, T3, T4, T5, T6) (R, bool), T0, T1, T2, T3, T4, T5, T6, R any](f F) func(T0, T1, T2, T3, T4, T5, T6) Option[R] {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6) Option[R] {
return optionize(func() (R, bool) {
return f(t0, t1, t2, t3, t4, t5, t6)
})
}
}
// Unoptionize7 converts a function with 7 parameters returning a tuple of a return value R and a boolean into a function with 7 parameters returning an Option[R]
func Unoptionize7[F ~func(T0, T1, T2, T3, T4, T5, T6) Option[R], T0, T1, T2, T3, T4, T5, T6, R any](f F) func(T0, T1, T2, T3, T4, T5, T6) (R, bool) {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6) (R, bool) {
return Unwrap(f(t0, t1, t2, t3, t4, t5, t6))
}
}
// Optionize8 converts a function with 8 parameters returning a tuple of a return value R and a boolean into a function with 8 parameters returning an Option[R]
func Optionize8[F ~func(T0, T1, T2, T3, T4, T5, T6, T7) (R, bool), T0, T1, T2, T3, T4, T5, T6, T7, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7) Option[R] {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7) Option[R] {
return optionize(func() (R, bool) {
return f(t0, t1, t2, t3, t4, t5, t6, t7)
})
}
}
// Unoptionize8 converts a function with 8 parameters returning a tuple of a return value R and a boolean into a function with 8 parameters returning an Option[R]
func Unoptionize8[F ~func(T0, T1, T2, T3, T4, T5, T6, T7) Option[R], T0, T1, T2, T3, T4, T5, T6, T7, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7) (R, bool) {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7) (R, bool) {
return Unwrap(f(t0, t1, t2, t3, t4, t5, t6, t7))
}
}
// Optionize9 converts a function with 9 parameters returning a tuple of a return value R and a boolean into a function with 9 parameters returning an Option[R]
func Optionize9[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8) (R, bool), T0, T1, T2, T3, T4, T5, T6, T7, T8, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8) Option[R] {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8) Option[R] {
return optionize(func() (R, bool) {
return f(t0, t1, t2, t3, t4, t5, t6, t7, t8)
})
}
}
// Unoptionize9 converts a function with 9 parameters returning a tuple of a return value R and a boolean into a function with 9 parameters returning an Option[R]
func Unoptionize9[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8) Option[R], T0, T1, T2, T3, T4, T5, T6, T7, T8, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8) (R, bool) {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8) (R, bool) {
return Unwrap(f(t0, t1, t2, t3, t4, t5, t6, t7, t8))
}
}
// Optionize10 converts a function with 10 parameters returning a tuple of a return value R and a boolean into a function with 10 parameters returning an Option[R]
func Optionize10[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (R, bool), T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) Option[R] {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9) Option[R] {
return optionize(func() (R, bool) {
return f(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9)
})
}
}
// Unoptionize10 converts a function with 10 parameters returning a tuple of a return value R and a boolean into a function with 10 parameters returning an Option[R]
func Unoptionize10[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) Option[R], T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (R, bool) {
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9) (R, bool) {
return Unwrap(f(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9))
}
}

View File

@@ -1,12 +1,19 @@
package option
import (
F "github.com/ibm/fp-go/function"
)
func toType[T any](a any) (T, bool) {
b, ok := a.(T)
return b, ok
}
func ToType[T any](src any) Option[T] {
return fromValidation(src, toType[T])
return F.Pipe1(
src,
Optionize1(toType[T]),
)
}
func ToAny[T any](src T) Option[any] {