1
0
mirror of https://github.com/IBM/fp-go.git synced 2025-08-26 19:38:58 +02:00

Compare commits

...

20 Commits

Author SHA1 Message Date
Carsten Leue
dc894ad643 Merge pull request #48 from IBM/cleue-some-benchmarking
fix: add some benchmarks
2023-09-19 10:22:04 +02:00
Dr. Carsten Leue
c902058320 fix: add some benchmarks
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
2023-09-19 10:21:16 +02:00
Carsten Leue
bf33f4fb66 Merge pull request #46 from a-lipson/main
Modified doc for generateTupled functions (& changed occurences)
2023-09-19 10:12:57 +02:00
Dre
b4d2a5c6be fixed typo in ioeither ChainFirstIOK doc line 2023-09-18 15:48:00 -07:00
a-lipson
705b71d95c Modified doc for generateTupled functions (& changed occurences) 2023-09-15 17:01:11 -07:00
Carsten Leue
34844bcfc2 Merge pull request #45 from IBM/cleue-prefer-second-over-SK
doc: ad doc to SK function
2023-09-13 15:04:50 +02:00
Dr. Carsten Leue
9a9d13b066 doc: ad doc to SK function
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
2023-09-13 15:04:19 +02:00
Carsten Leue
da1449e680 Merge pull request #44 from IBM/cleue-add-apply-monoid
fix: add missing alt methods and semigroup
2023-09-12 22:16:20 +02:00
Dr. Carsten Leue
865d9fe064 fix: add missing alt methods and semigroup
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
2023-09-12 22:10:33 +02:00
Carsten Leue
c5b1bae65a Merge pull request #43 from IBM/cleue-add-custom-type-sample
Cleue add custom type sample
2023-09-12 13:47:12 +02:00
Dr. Carsten Leue
0a395f63ff fix: merge
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
2023-09-12 13:45:07 +02:00
Dr. Carsten Leue
26a7066de0 fix: add UnslicedN
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
2023-09-12 13:28:23 +02:00
Dr. Carsten Leue
52823e2c8e fix: add UnslicedN
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
2023-09-12 10:52:39 +02:00
Carsten Leue
503021c65e Merge pull request #42 from IBM/cleue-add-traverse-with-index
fix: add missing withIndex methods
2023-09-11 13:50:30 +02:00
Dr. Carsten Leue
a2a6a41993 fix: add missing withIndex methods
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
2023-09-11 13:48:51 +02:00
Carsten Leue
7da9de6f41 Merge pull request #41 from IBM/cleue-add-missing-functions
fix: order of parameters in optics
2023-09-10 21:56:23 +02:00
Dr. Carsten Leue
ff1b6faf84 fix: order of parameters in optics
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
2023-09-10 21:49:44 +02:00
Carsten Leue
38120764e7 Merge pull request #40 from IBM/cleue-add-missing-lenses
fix: change Cache to Memoize and fix order of parameters to ToType
2023-09-10 21:37:38 +02:00
Dr. Carsten Leue
a83c2aec49 fix: change Cache to Memoize and fix order of parameters to ToType
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
2023-09-10 21:29:01 +02:00
Carsten Leue
03debd37c8 Merge pull request #39 from IBM/cleue-implement-compact
fix: add compact methods
2023-09-08 22:57:18 +02:00
91 changed files with 1361 additions and 81 deletions

View File

@@ -187,6 +187,14 @@ func IsEmpty[AS ~[]A, A any](as AS) bool {
return array.IsEmpty(as)
}
func IsNil[GA ~[]A, A any](as GA) bool {
return array.IsNil(as)
}
func IsNonNil[GA ~[]A, A any](as GA) bool {
return array.IsNonNil(as)
}
func Match[AS ~[]A, A, B any](onEmpty func() B, onNonEmpty func(AS) B) func(AS) B {
return func(as AS) B {
if IsEmpty(as) {

View File

@@ -25,6 +25,40 @@ import (
C "github.com/urfave/cli/v2"
)
func generateUnsliced(f *os.File, i int) {
// Create the optionize version
fmt.Fprintf(f, "\n// Unsliced%d converts a function taking a slice parameter into a function with %d parameters\n", i, i)
fmt.Fprintf(f, "func Unsliced%d[F ~func([]T) R, T, R any](f F) func(", i)
for j := 0; j < i; j++ {
if j > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "T")
}
fmt.Fprintf(f, ") R {\n")
fmt.Fprintf(f, " return func(")
for j := 0; j < i; j++ {
if j > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "t%d", j+1)
}
if i > 0 {
fmt.Fprintf(f, " T")
}
fmt.Fprintf(f, ") R {\n")
fmt.Fprintf(f, " return f([]T{")
for j := 0; j < i; j++ {
if j > 0 {
fmt.Fprintf(f, ", ")
}
fmt.Fprintf(f, "t%d", j+1)
}
fmt.Fprintln(f, "})")
fmt.Fprintln(f, " }")
fmt.Fprintln(f, "}")
}
func generateVariadic(f *os.File, i int) {
// Create the nullary version
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)
@@ -83,7 +117,7 @@ func generateVariadic(f *os.File, i int) {
fmt.Fprintf(f, "v)\n")
fmt.Fprintf(f, " }\n")
fmt.Fprintf(f, "}")
fmt.Fprintf(f, "}\n")
}
func generateUnvariadic(f *os.File, i int) {
@@ -144,7 +178,7 @@ func generateUnvariadic(f *os.File, i int) {
fmt.Fprintf(f, "v...)\n")
fmt.Fprintf(f, " }\n")
fmt.Fprintf(f, "}")
fmt.Fprintf(f, "}\n")
}
func generateNullary(f *os.File, i int) {
@@ -347,6 +381,8 @@ func generatePipeHelpers(filename string, count int) error {
generateVariadic(f, 0)
// unvariadic
generateUnvariadic(f, 0)
// unsliced
generateUnsliced(f, 0)
for i := 1; i <= count; i++ {
@@ -364,6 +400,8 @@ func generatePipeHelpers(filename string, count int) error {
generateVariadic(f, i)
// unvariadic
generateUnvariadic(f, i)
// unsliced
generateUnsliced(f, i)
}
return nil

View File

@@ -338,7 +338,7 @@ func generateUntupled(f *os.File, i int) {
func generateTupled(f *os.File, i int) {
// Create the optionize version
fmt.Fprintf(f, "\n// Tupled%d converts a function with %d parameters returning into a function taking a Tuple%d\n// The inverse function is [Untupled%d]\n", i, i, i, i)
fmt.Fprintf(f, "\n// Tupled%d converts a function with %d parameters into a function taking a Tuple%d\n// The inverse function is [Untupled%d]\n", i, i, i, i)
fmt.Fprintf(f, "func Tupled%d[F ~func(", i)
for j := 0; j < i; j++ {
if j > 0 {

View File

@@ -24,6 +24,11 @@ func TraverseArray[A, B any](f func(A) Reader[B]) func([]A) Reader[[]B] {
return R.TraverseArray[Reader[B], Reader[[]B], []A](f)
}
// TraverseArrayWithIndex transforms an array
func TraverseArrayWithIndex[A, B any](f func(int, A) Reader[B]) func([]A) Reader[[]B] {
return R.TraverseArrayWithIndex[Reader[B], Reader[[]B], []A](f)
}
// SequenceArray converts a homogeneous sequence of either into an either of sequence
func SequenceArray[A any](ma []Reader[A]) Reader[[]A] {
return R.SequenceArray[Reader[A], Reader[[]A]](ma)

View File

@@ -24,6 +24,11 @@ func TraverseArray[A, B any](f func(A) ReaderEither[B]) func([]A) ReaderEither[[
return RE.TraverseArray[ReaderEither[B], ReaderEither[[]B], []A](f)
}
// TraverseArrayWithIndex transforms an array
func TraverseArrayWithIndex[A, B any](f func(int, A) ReaderEither[B]) func([]A) ReaderEither[[]B] {
return RE.TraverseArrayWithIndex[ReaderEither[B], ReaderEither[[]B], []A](f)
}
// SequenceArray converts a homogeneous sequence of either into an either of sequence
func SequenceArray[A any](ma []ReaderEither[A]) ReaderEither[[]A] {
return RE.SequenceArray[ReaderEither[A], ReaderEither[[]A]](ma)

View File

@@ -25,6 +25,11 @@ func TraverseArray[A, B any](f func(A) ReaderIO[B]) func([]A) ReaderIO[[]B] {
return R.TraverseArray[ReaderIO[B], ReaderIO[[]B], IO.IO[B], IO.IO[[]B], []A](f)
}
// TraverseArrayWithIndex transforms an array
func TraverseArrayWithIndex[A, B any](f func(int, A) ReaderIO[B]) func([]A) ReaderIO[[]B] {
return R.TraverseArrayWithIndex[ReaderIO[B], ReaderIO[[]B], IO.IO[B], IO.IO[[]B], []A](f)
}
// SequenceArray converts a homogeneous sequence of either into an either of sequence
func SequenceArray[A any](ma []ReaderIO[A]) ReaderIO[[]A] {
return R.SequenceArray[ReaderIO[A], ReaderIO[[]A]](ma)

View File

@@ -2,7 +2,7 @@ package readerioeither
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-08-17 22:58:56.457404 +0200 CEST m=+0.024265101
// 2023-09-12 13:44:14.1022311 +0200 CEST m=+0.017763401
import (
"context"

View File

@@ -2,7 +2,7 @@ package generic
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-08-17 22:58:56.457404 +0200 CEST m=+0.024265101
// 2023-09-12 13:44:14.1036885 +0200 CEST m=+0.019220801
import (
"context"

View File

@@ -0,0 +1,56 @@
// 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 generic
import (
"context"
ET "github.com/IBM/fp-go/either"
M "github.com/IBM/fp-go/monoid"
)
func ApplicativeMonoid[GRA ~func(context.Context) GIOA, GRFA ~func(context.Context) GIOFA, GIOA ~func() ET.Either[error, A], GIOFA ~func() ET.Either[error, func(A) A], A any](
m M.Monoid[A],
) M.Monoid[GRA] {
return M.ApplicativeMonoid(
Of[GRA],
MonadMap[GRA, GRFA],
MonadAp[GRA, GRA, GRFA],
m,
)
}
func ApplicativeMonoidSeq[GRA ~func(context.Context) GIOA, GRFA ~func(context.Context) GIOFA, GIOA ~func() ET.Either[error, A], GIOFA ~func() ET.Either[error, func(A) A], A any](
m M.Monoid[A],
) M.Monoid[GRA] {
return M.ApplicativeMonoid(
Of[GRA],
MonadMap[GRA, GRFA],
MonadApSeq[GRA, GRA, GRFA],
m,
)
}
func ApplicativeMonoidPar[GRA ~func(context.Context) GIOA, GRFA ~func(context.Context) GIOFA, GIOA ~func() ET.Either[error, A], GIOFA ~func() ET.Either[error, func(A) A], A any](
m M.Monoid[A],
) M.Monoid[GRA] {
return M.ApplicativeMonoid(
Of[GRA],
MonadMap[GRA, GRFA],
MonadApPar[GRA, GRA, GRFA],
m,
)
}

View File

@@ -543,3 +543,11 @@ func TryCatch[
A any](f func(context.Context) func() (A, error)) GRA {
return RIE.TryCatch[GRA](f, ER.IdentityError)
}
func MonadAlt[LAZY ~func() GEA, GEA ~func(context.Context) GIOA, GIOA ~func() E.Either[error, A], A any](first GEA, second LAZY) GEA {
return RIE.MonadAlt(first, second)
}
func Alt[LAZY ~func() GEA, GEA ~func(context.Context) GIOA, GIOA ~func() E.Either[error, A], A any](second LAZY) func(GEA) GEA {
return RIE.Alt(second)
}

View File

@@ -0,0 +1,29 @@
// 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 generic
import (
"context"
ET "github.com/IBM/fp-go/either"
S "github.com/IBM/fp-go/semigroup"
)
func AltSemigroup[GRA ~func(context.Context) GIOA, GIOA ~func() ET.Either[error, A], A any]() S.Semigroup[GRA] {
return S.AltSemigroup(
MonadAlt[func() GRA],
)
}

View File

@@ -62,6 +62,25 @@ func TraverseArray[
)
}
// TraverseArrayWithIndex transforms an array
func TraverseArrayWithIndex[
AS ~[]A,
GRBS ~func(context.Context) GIOBS,
GRB ~func(context.Context) GIOB,
GIOBS ~func() E.Either[error, BS],
GIOB ~func() E.Either[error, B],
BS ~[]B,
A, B any](f func(int, A) GRB) func(AS) GRBS {
return RA.TraverseWithIndex[AS](
Of[GRBS, GIOBS, BS],
Map[GRBS, func(context.Context) func() E.Either[error, func(B) BS], GIOBS, func() E.Either[error, func(B) BS], BS, func(B) BS],
Ap[GRBS, func(context.Context) func() E.Either[error, func(B) BS], GRB],
f,
)
}
// SequenceArray converts a homogeneous sequence of either into an either of sequence
func SequenceArray[
AS ~[]A,
@@ -115,6 +134,26 @@ func TraverseRecord[K comparable,
)
}
// TraverseRecordWithIndex transforms a record
func TraverseRecordWithIndex[K comparable,
AS ~map[K]A,
GRBS ~func(context.Context) GIOBS,
GRB ~func(context.Context) GIOB,
GIOBS ~func() E.Either[error, BS],
GIOB ~func() E.Either[error, B],
BS ~map[K]B,
A, B any](f func(K, A) GRB) func(AS) GRBS {
return RR.TraverseWithIndex[AS](
Of[GRBS, GIOBS, BS],
Map[GRBS, func(context.Context) func() E.Either[error, func(B) BS], GIOBS, func() E.Either[error, func(B) BS], BS, func(B) BS],
Ap[GRBS, func(context.Context) func() E.Either[error, func(B) BS], GRB],
f,
)
}
// SequenceRecord converts a homogeneous sequence of either into an either of sequence
func SequenceRecord[K comparable,
AS ~map[K]A,

View File

@@ -0,0 +1,36 @@
// 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 readerioeither
import (
G "github.com/IBM/fp-go/context/readerioeither/generic"
M "github.com/IBM/fp-go/monoid"
)
// ApplicativeMonoid returns a [Monoid] that concatenates [ReaderIOEither] instances via their applicative
func ApplicativeMonoid[A any](m M.Monoid[A]) M.Monoid[ReaderIOEither[A]] {
return G.ApplicativeMonoid[ReaderIOEither[A], ReaderIOEither[func(A) A]](m)
}
// ApplicativeMonoidSeq returns a [Monoid] that concatenates [ReaderIOEither] instances via their applicative
func ApplicativeMonoidSeq[A any](m M.Monoid[A]) M.Monoid[ReaderIOEither[A]] {
return G.ApplicativeMonoidSeq[ReaderIOEither[A], ReaderIOEither[func(A) A]](m)
}
// ApplicativeMonoidPar returns a [Monoid] that concatenates [ReaderIOEither] instances via their applicative
func ApplicativeMonoidPar[A any](m M.Monoid[A]) M.Monoid[ReaderIOEither[A]] {
return G.ApplicativeMonoidPar[ReaderIOEither[A], ReaderIOEither[func(A) A]](m)
}

View File

@@ -25,6 +25,7 @@ import (
ET "github.com/IBM/fp-go/either"
IO "github.com/IBM/fp-go/io"
IOE "github.com/IBM/fp-go/ioeither"
L "github.com/IBM/fp-go/lazy"
O "github.com/IBM/fp-go/option"
)
@@ -182,7 +183,7 @@ func Timer(delay time.Duration) ReaderIOEither[time.Time] {
}
// Defer creates an IO by creating a brand new IO via a generator function, each time
func Defer[A any](gen func() ReaderIOEither[A]) ReaderIOEither[A] {
func Defer[A any](gen L.Lazy[ReaderIOEither[A]]) ReaderIOEither[A] {
return G.Defer[ReaderIOEither[A]](gen)
}
@@ -190,3 +191,13 @@ func Defer[A any](gen func() ReaderIOEither[A]) ReaderIOEither[A] {
func TryCatch[A any](f func(context.Context) func() (A, error)) ReaderIOEither[A] {
return G.TryCatch[ReaderIOEither[A]](f)
}
// MonadAlt identifies an associative operation on a type constructor
func MonadAlt[A any](first ReaderIOEither[A], second L.Lazy[ReaderIOEither[A]]) ReaderIOEither[A] {
return G.MonadAlt(first, second)
}
// Alt identifies an associative operation on a type constructor
func Alt[A any](second L.Lazy[ReaderIOEither[A]]) func(ReaderIOEither[A]) ReaderIOEither[A] {
return G.Alt(second)
}

View File

@@ -0,0 +1,26 @@
// 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 readerioeither
import (
G "github.com/IBM/fp-go/context/readerioeither/generic"
S "github.com/IBM/fp-go/semigroup"
)
// AltSemigroup is a [Semigroup] that tries the first item and then the second one using an alternative
func AltSemigroup[A any]() S.Semigroup[ReaderIOEither[A]] {
return G.AltSemigroup[ReaderIOEither[A]]()
}

View File

@@ -24,6 +24,11 @@ func TraverseArray[A, B any](f func(A) ReaderIOEither[B]) func([]A) ReaderIOEith
return G.TraverseArray[[]A, ReaderIOEither[[]B]](f)
}
// TraverseArrayWithIndex uses transforms an array [[]A] into [[]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[[]B]]
func TraverseArrayWithIndex[A, B any](f func(int, A) ReaderIOEither[B]) func([]A) ReaderIOEither[[]B] {
return G.TraverseArrayWithIndex[[]A, ReaderIOEither[[]B]](f)
}
// SequenceArray converts a homogeneous sequence of either into an either of sequence
func SequenceArray[A any](ma []ReaderIOEither[A]) ReaderIOEither[[]A] {
return G.SequenceArray[[]A, []ReaderIOEither[A], ReaderIOEither[[]A]](ma)
@@ -34,6 +39,11 @@ func TraverseRecord[K comparable, A, B any](f func(A) ReaderIOEither[B]) func(ma
return G.TraverseRecord[K, map[K]A, ReaderIOEither[map[K]B]](f)
}
// TraverseRecordWithIndex uses transforms a record [map[K]A] into [map[K]ReaderIOEither[B]] and then resolves that into a [ReaderIOEither[map[K]B]]
func TraverseRecordWithIndex[K comparable, A, B any](f func(K, A) ReaderIOEither[B]) func(map[K]A) ReaderIOEither[map[K]B] {
return G.TraverseRecordWithIndex[K, map[K]A, ReaderIOEither[map[K]B]](f)
}
// SequenceRecord converts a homogeneous sequence of either into an either of sequence
func SequenceRecord[K comparable, A any](ma map[K]ReaderIOEither[A]) ReaderIOEither[map[K]A] {
return G.SequenceRecord[K, map[K]A, map[K]ReaderIOEither[A], ReaderIOEither[map[K]A]](ma)

2
coverage.bat Normal file
View File

@@ -0,0 +1,2 @@
@echo off
go tool cover -html=build/cover.out -o build/cover.html

View File

@@ -24,6 +24,7 @@ func ApplySemigroup[E, A any](s S.Semigroup[A]) S.Semigroup[Either[E, A]] {
return S.ApplySemigroup(MonadMap[E, A, func(A) A], MonadAp[A, E, A], s)
}
// ApplicativeMonoid returns a [Monoid] that concatenates [Either] instances via their applicative
func ApplicativeMonoid[E, A any](m M.Monoid[A]) M.Monoid[Either[E, A]] {
return M.ApplicativeMonoid(Of[E, A], MonadMap[E, A, func(A) A], MonadAp[A, E, A], m)
}

View File

@@ -20,7 +20,7 @@ import (
RA "github.com/IBM/fp-go/internal/array"
)
// TraverseArray transforms an array
// TraverseArrayG transforms an array
func TraverseArrayG[GA ~[]A, GB ~[]B, E, A, B any](f func(A) Either[E, B]) func(GA) Either[E, GB] {
return RA.Traverse[GA](
Of[E, GB],
@@ -36,6 +36,22 @@ func TraverseArray[E, A, B any](f func(A) Either[E, B]) func([]A) Either[E, []B]
return TraverseArrayG[[]A, []B](f)
}
// TraverseArrayWithIndexG transforms an array
func TraverseArrayWithIndexG[GA ~[]A, GB ~[]B, E, A, B any](f func(int, A) Either[E, B]) func(GA) Either[E, GB] {
return RA.TraverseWithIndex[GA](
Of[E, GB],
Map[E, GB, func(B) GB],
Ap[GB, E, B],
f,
)
}
// TraverseArrayWithIndex transforms an array
func TraverseArrayWithIndex[E, A, B any](f func(int, A) Either[E, B]) func([]A) Either[E, []B] {
return TraverseArrayWithIndexG[[]A, []B](f)
}
func SequenceArrayG[GA ~[]A, GOA ~[]Either[E, A], E, A any](ma GOA) Either[E, GA] {
return TraverseArrayG[GOA, GA](F.Identity[Either[E, A]])(ma)
}

View File

@@ -209,7 +209,7 @@ func OrElse[E, A any](onLeft func(e E) Either[E, A]) func(Either[E, A]) Either[E
return Fold(onLeft, Of[E, A])
}
func ToType[E, A any](onError func(any) E) func(any) Either[E, A] {
func ToType[A, E any](onError func(any) E) func(any) Either[E, A] {
return func(value any) Either[E, A] {
return F.Pipe2(
value,

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-08-17 22:58:57.9925506 +0200 CEST m=+0.033401101
// 2023-09-12 13:44:15.6356542 +0200 CEST m=+0.009418901
package either

View File

@@ -20,7 +20,7 @@ import (
RR "github.com/IBM/fp-go/internal/record"
)
// TraverseRecord transforms a record of options into an option of a record
// TraverseRecordG transforms a record of options into an option of a record
func TraverseRecordG[GA ~map[K]A, GB ~map[K]B, K comparable, E, A, B any](f func(A) Either[E, B]) func(GA) Either[E, GB] {
return RR.Traverse[GA](
Of[E, GB],
@@ -35,6 +35,21 @@ func TraverseRecord[K comparable, E, A, B any](f func(A) Either[E, B]) func(map[
return TraverseRecordG[map[K]A, map[K]B](f)
}
// TraverseRecordWithIndexG transforms a record of options into an option of a record
func TraverseRecordWithIndexG[GA ~map[K]A, GB ~map[K]B, K comparable, E, A, B any](f func(K, A) Either[E, B]) func(GA) Either[E, GB] {
return RR.TraverseWithIndex[GA](
Of[E, GB],
Map[E, GB, func(B) GB],
Ap[GB, E, B],
f,
)
}
// TraverseRecordWithIndex transforms a record of eithers into an either of a record
func TraverseRecordWithIndex[K comparable, E, A, B any](f func(K, A) Either[E, B]) func(map[K]A) Either[E, map[K]B] {
return TraverseRecordWithIndexG[map[K]A, map[K]B](f)
}
func SequenceRecordG[GA ~map[K]A, GOA ~map[K]Either[E, A], K comparable, E, A any](ma GOA) Either[E, GA] {
return TraverseRecordG[GOA, GA](F.Identity[Either[E, A]])(ma)
}

View File

@@ -26,6 +26,7 @@ func Bind2nd[T1, T2, R any](f func(T1, T2) R, t2 T2) func(T1) R {
}
}
// SK function (SKI combinator calculus).
func SK[T1, T2 any](_ T1, t2 T2) T2 {
return t2
}

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-08-17 22:59:01.9404821 +0200 CEST m=+0.161366801
// 2023-09-12 13:44:23.4226437 +0200 CEST m=+0.011841001
package function

View File

@@ -19,12 +19,12 @@ import (
G "github.com/IBM/fp-go/function/generic"
)
// Cache converts a unary function into a unary function that caches the value depending on the parameter
func Cache[K comparable, T any](f func(K) T) func(K) T {
return G.Cache(f)
// Memoize converts a unary function into a unary function that caches the value depending on the parameter
func Memoize[K comparable, T any](f func(K) T) func(K) T {
return G.Memoize(f)
}
// ContramapCache converts a unary function into a unary function that caches the value depending on the parameter
func ContramapCache[A any, K comparable, T any](kf func(A) K) func(func(A) T) func(A) T {
return G.ContramapCache[func(A) T](kf)
// ContramapMemoize converts a unary function into a unary function that caches the value depending on the parameter
func ContramapMemoize[A any, K comparable, T any](kf func(A) K) func(func(A) T) func(A) T {
return G.ContramapMemoize[func(A) T](kf)
}

View File

@@ -29,7 +29,7 @@ func TestCache(t *testing.T) {
return n
}
cached := Cache(withSideEffect)
cached := Memoize(withSideEffect)
assert.Equal(t, 0, count)

View File

@@ -62,6 +62,7 @@ func First[T1, T2 any](t1 T1, _ T2) T1 {
}
// Second returns the second out of two input values
// Identical to [SK]
func Second[T1, T2 any](_ T1, t2 T2) T2 {
return t2
}

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-08-17 22:58:59.8663985 +0200 CEST m=+0.103744101
// 2023-09-12 13:44:17.0002767 +0200 CEST m=+0.008233101
package function
@@ -24,6 +24,13 @@ func Unvariadic0[V, R any](f func(...V) R) func([]V) R {
}
}
// Unsliced0 converts a function taking a slice parameter into a function with 0 parameters
func Unsliced0[F ~func([]T) R, T, R any](f F) func() R {
return func() R {
return f([]T{})
}
}
// Pipe1 takes an initial value t0 and successively applies 1 functions where the input of a function is the return value of the previous function
// The final return value is the result of the last function application
func Pipe1[F1 ~func(T0) T1, T0, T1 any](t0 T0, f1 F1) T1 {
@@ -76,6 +83,13 @@ func Unvariadic1[T1, V, R any](f func(T1, ...V) R) func(T1, []V) R {
}
}
// Unsliced1 converts a function taking a slice parameter into a function with 1 parameters
func Unsliced1[F ~func([]T) R, T, R any](f F) func(T) R {
return func(t1 T) R {
return f([]T{t1})
}
}
// Pipe2 takes an initial value t0 and successively applies 2 functions where the input of a function is the return value of the previous function
// The final return value is the result of the last function application
func Pipe2[F1 ~func(T0) T1, F2 ~func(T1) T2, T0, T1, T2 any](t0 T0, f1 F1, f2 F2) T2 {
@@ -131,6 +145,13 @@ func Unvariadic2[T1, T2, V, R any](f func(T1, T2, ...V) R) func(T1, T2, []V) R {
}
}
// Unsliced2 converts a function taking a slice parameter into a function with 2 parameters
func Unsliced2[F ~func([]T) R, T, R any](f F) func(T, T) R {
return func(t1, t2 T) R {
return f([]T{t1, t2})
}
}
// Pipe3 takes an initial value t0 and successively applies 3 functions where the input of a function is the return value of the previous function
// The final return value is the result of the last function application
func Pipe3[F1 ~func(T0) T1, F2 ~func(T1) T2, F3 ~func(T2) T3, T0, T1, T2, T3 any](t0 T0, f1 F1, f2 F2, f3 F3) T3 {
@@ -189,6 +210,13 @@ func Unvariadic3[T1, T2, T3, V, R any](f func(T1, T2, T3, ...V) R) func(T1, T2,
}
}
// Unsliced3 converts a function taking a slice parameter into a function with 3 parameters
func Unsliced3[F ~func([]T) R, T, R any](f F) func(T, T, T) R {
return func(t1, t2, t3 T) R {
return f([]T{t1, t2, t3})
}
}
// Pipe4 takes an initial value t0 and successively applies 4 functions where the input of a function is the return value of the previous function
// The final return value is the result of the last function application
func Pipe4[F1 ~func(T0) T1, F2 ~func(T1) T2, F3 ~func(T2) T3, F4 ~func(T3) T4, T0, T1, T2, T3, T4 any](t0 T0, f1 F1, f2 F2, f3 F3, f4 F4) T4 {
@@ -250,6 +278,13 @@ func Unvariadic4[T1, T2, T3, T4, V, R any](f func(T1, T2, T3, T4, ...V) R) func(
}
}
// Unsliced4 converts a function taking a slice parameter into a function with 4 parameters
func Unsliced4[F ~func([]T) R, T, R any](f F) func(T, T, T, T) R {
return func(t1, t2, t3, t4 T) R {
return f([]T{t1, t2, t3, t4})
}
}
// Pipe5 takes an initial value t0 and successively applies 5 functions where the input of a function is the return value of the previous function
// The final return value is the result of the last function application
func Pipe5[F1 ~func(T0) T1, F2 ~func(T1) T2, F3 ~func(T2) T3, F4 ~func(T3) T4, F5 ~func(T4) T5, T0, T1, T2, T3, T4, T5 any](t0 T0, f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) T5 {
@@ -314,6 +349,13 @@ func Unvariadic5[T1, T2, T3, T4, T5, V, R any](f func(T1, T2, T3, T4, T5, ...V)
}
}
// Unsliced5 converts a function taking a slice parameter into a function with 5 parameters
func Unsliced5[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T) R {
return func(t1, t2, t3, t4, t5 T) R {
return f([]T{t1, t2, t3, t4, t5})
}
}
// Pipe6 takes an initial value t0 and successively applies 6 functions where the input of a function is the return value of the previous function
// The final return value is the result of the last function application
func Pipe6[F1 ~func(T0) T1, F2 ~func(T1) T2, F3 ~func(T2) T3, F4 ~func(T3) T4, F5 ~func(T4) T5, F6 ~func(T5) T6, T0, T1, T2, T3, T4, T5, T6 any](t0 T0, f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) T6 {
@@ -381,6 +423,13 @@ func Unvariadic6[T1, T2, T3, T4, T5, T6, V, R any](f func(T1, T2, T3, T4, T5, T6
}
}
// Unsliced6 converts a function taking a slice parameter into a function with 6 parameters
func Unsliced6[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T) R {
return func(t1, t2, t3, t4, t5, t6 T) R {
return f([]T{t1, t2, t3, t4, t5, t6})
}
}
// Pipe7 takes an initial value t0 and successively applies 7 functions where the input of a function is the return value of the previous function
// The final return value is the result of the last function application
func Pipe7[F1 ~func(T0) T1, F2 ~func(T1) T2, F3 ~func(T2) T3, F4 ~func(T3) T4, F5 ~func(T4) T5, F6 ~func(T5) T6, F7 ~func(T6) T7, T0, T1, T2, T3, T4, T5, T6, T7 any](t0 T0, f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) T7 {
@@ -451,6 +500,13 @@ func Unvariadic7[T1, T2, T3, T4, T5, T6, T7, V, R any](f func(T1, T2, T3, T4, T5
}
}
// Unsliced7 converts a function taking a slice parameter into a function with 7 parameters
func Unsliced7[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T) R {
return func(t1, t2, t3, t4, t5, t6, t7 T) R {
return f([]T{t1, t2, t3, t4, t5, t6, t7})
}
}
// Pipe8 takes an initial value t0 and successively applies 8 functions where the input of a function is the return value of the previous function
// The final return value is the result of the last function application
func Pipe8[F1 ~func(T0) T1, F2 ~func(T1) T2, F3 ~func(T2) T3, F4 ~func(T3) T4, F5 ~func(T4) T5, F6 ~func(T5) T6, F7 ~func(T6) T7, F8 ~func(T7) T8, T0, T1, T2, T3, T4, T5, T6, T7, T8 any](t0 T0, f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) T8 {
@@ -524,6 +580,13 @@ func Unvariadic8[T1, T2, T3, T4, T5, T6, T7, T8, V, R any](f func(T1, T2, T3, T4
}
}
// Unsliced8 converts a function taking a slice parameter into a function with 8 parameters
func Unsliced8[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T) R {
return func(t1, t2, t3, t4, t5, t6, t7, t8 T) R {
return f([]T{t1, t2, t3, t4, t5, t6, t7, t8})
}
}
// Pipe9 takes an initial value t0 and successively applies 9 functions where the input of a function is the return value of the previous function
// The final return value is the result of the last function application
func Pipe9[F1 ~func(T0) T1, F2 ~func(T1) T2, F3 ~func(T2) T3, F4 ~func(T3) T4, F5 ~func(T4) T5, F6 ~func(T5) T6, F7 ~func(T6) T7, F8 ~func(T7) T8, F9 ~func(T8) T9, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t0 T0, f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) T9 {
@@ -600,6 +663,13 @@ func Unvariadic9[T1, T2, T3, T4, T5, T6, T7, T8, T9, V, R any](f func(T1, T2, T3
}
}
// Unsliced9 converts a function taking a slice parameter into a function with 9 parameters
func Unsliced9[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T) R {
return func(t1, t2, t3, t4, t5, t6, t7, t8, t9 T) R {
return f([]T{t1, t2, t3, t4, t5, t6, t7, t8, t9})
}
}
// Pipe10 takes an initial value t0 and successively applies 10 functions where the input of a function is the return value of the previous function
// The final return value is the result of the last function application
func Pipe10[F1 ~func(T0) T1, F2 ~func(T1) T2, F3 ~func(T2) T3, F4 ~func(T3) T4, F5 ~func(T4) T5, F6 ~func(T5) T6, F7 ~func(T6) T7, F8 ~func(T7) T8, F9 ~func(T8) T9, F10 ~func(T9) T10, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t0 T0, f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) T10 {
@@ -679,6 +749,13 @@ func Unvariadic10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, V, R any](f func(T1,
}
}
// Unsliced10 converts a function taking a slice parameter into a function with 10 parameters
func Unsliced10[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T, T) R {
return func(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10 T) R {
return f([]T{t1, t2, t3, t4, t5, t6, t7, t8, t9, t10})
}
}
// Pipe11 takes an initial value t0 and successively applies 11 functions where the input of a function is the return value of the previous function
// The final return value is the result of the last function application
func Pipe11[F1 ~func(T0) T1, F2 ~func(T1) T2, F3 ~func(T2) T3, F4 ~func(T3) T4, F5 ~func(T4) T5, F6 ~func(T5) T6, F7 ~func(T6) T7, F8 ~func(T7) T8, F9 ~func(T8) T9, F10 ~func(T9) T10, F11 ~func(T10) T11, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 any](t0 T0, f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11) T11 {
@@ -761,6 +838,13 @@ func Unvariadic11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, V, R any](f func
}
}
// Unsliced11 converts a function taking a slice parameter into a function with 11 parameters
func Unsliced11[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T, T, T) R {
return func(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11 T) R {
return f([]T{t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11})
}
}
// Pipe12 takes an initial value t0 and successively applies 12 functions where the input of a function is the return value of the previous function
// The final return value is the result of the last function application
func Pipe12[F1 ~func(T0) T1, F2 ~func(T1) T2, F3 ~func(T2) T3, F4 ~func(T3) T4, F5 ~func(T4) T5, F6 ~func(T5) T6, F7 ~func(T6) T7, F8 ~func(T7) T8, F9 ~func(T8) T9, F10 ~func(T9) T10, F11 ~func(T10) T11, F12 ~func(T11) T12, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 any](t0 T0, f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12) T12 {
@@ -846,6 +930,13 @@ func Unvariadic12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, V, R any](f
}
}
// Unsliced12 converts a function taking a slice parameter into a function with 12 parameters
func Unsliced12[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T, T, T, T) R {
return func(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12 T) R {
return f([]T{t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12})
}
}
// Pipe13 takes an initial value t0 and successively applies 13 functions where the input of a function is the return value of the previous function
// The final return value is the result of the last function application
func Pipe13[F1 ~func(T0) T1, F2 ~func(T1) T2, F3 ~func(T2) T3, F4 ~func(T3) T4, F5 ~func(T4) T5, F6 ~func(T5) T6, F7 ~func(T6) T7, F8 ~func(T7) T8, F9 ~func(T8) T9, F10 ~func(T9) T10, F11 ~func(T10) T11, F12 ~func(T11) T12, F13 ~func(T12) T13, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 any](t0 T0, f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13) T13 {
@@ -934,6 +1025,13 @@ func Unvariadic13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, V, R a
}
}
// Unsliced13 converts a function taking a slice parameter into a function with 13 parameters
func Unsliced13[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T, T, T, T, T) R {
return func(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13 T) R {
return f([]T{t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13})
}
}
// Pipe14 takes an initial value t0 and successively applies 14 functions where the input of a function is the return value of the previous function
// The final return value is the result of the last function application
func Pipe14[F1 ~func(T0) T1, F2 ~func(T1) T2, F3 ~func(T2) T3, F4 ~func(T3) T4, F5 ~func(T4) T5, F6 ~func(T5) T6, F7 ~func(T6) T7, F8 ~func(T7) T8, F9 ~func(T8) T9, F10 ~func(T9) T10, F11 ~func(T10) T11, F12 ~func(T11) T12, F13 ~func(T12) T13, F14 ~func(T13) T14, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 any](t0 T0, f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13, f14 F14) T14 {
@@ -1025,6 +1123,13 @@ func Unvariadic14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, V
}
}
// Unsliced14 converts a function taking a slice parameter into a function with 14 parameters
func Unsliced14[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T, T, T, T, T, T) R {
return func(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14 T) R {
return f([]T{t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14})
}
}
// Pipe15 takes an initial value t0 and successively applies 15 functions where the input of a function is the return value of the previous function
// The final return value is the result of the last function application
func Pipe15[F1 ~func(T0) T1, F2 ~func(T1) T2, F3 ~func(T2) T3, F4 ~func(T3) T4, F5 ~func(T4) T5, F6 ~func(T5) T6, F7 ~func(T6) T7, F8 ~func(T7) T8, F9 ~func(T8) T9, F10 ~func(T9) T10, F11 ~func(T10) T11, F12 ~func(T11) T12, F13 ~func(T12) T13, F14 ~func(T13) T14, F15 ~func(T14) T15, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 any](t0 T0, f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13, f14 F14, f15 F15) T15 {
@@ -1119,6 +1224,13 @@ func Unvariadic15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T
}
}
// Unsliced15 converts a function taking a slice parameter into a function with 15 parameters
func Unsliced15[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) R {
return func(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15 T) R {
return f([]T{t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15})
}
}
// Pipe16 takes an initial value t0 and successively applies 16 functions where the input of a function is the return value of the previous function
// The final return value is the result of the last function application
func Pipe16[F1 ~func(T0) T1, F2 ~func(T1) T2, F3 ~func(T2) T3, F4 ~func(T3) T4, F5 ~func(T4) T5, F6 ~func(T5) T6, F7 ~func(T6) T7, F8 ~func(T7) T8, F9 ~func(T8) T9, F10 ~func(T9) T10, F11 ~func(T10) T11, F12 ~func(T11) T12, F13 ~func(T12) T13, F14 ~func(T13) T14, F15 ~func(T14) T15, F16 ~func(T15) T16, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16 any](t0 T0, f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13, f14 F14, f15 F15, f16 F16) T16 {
@@ -1216,6 +1328,13 @@ func Unvariadic16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T
}
}
// Unsliced16 converts a function taking a slice parameter into a function with 16 parameters
func Unsliced16[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) R {
return func(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16 T) R {
return f([]T{t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16})
}
}
// Pipe17 takes an initial value t0 and successively applies 17 functions where the input of a function is the return value of the previous function
// The final return value is the result of the last function application
func Pipe17[F1 ~func(T0) T1, F2 ~func(T1) T2, F3 ~func(T2) T3, F4 ~func(T3) T4, F5 ~func(T4) T5, F6 ~func(T5) T6, F7 ~func(T6) T7, F8 ~func(T7) T8, F9 ~func(T8) T9, F10 ~func(T9) T10, F11 ~func(T10) T11, F12 ~func(T11) T12, F13 ~func(T12) T13, F14 ~func(T13) T14, F15 ~func(T14) T15, F16 ~func(T15) T16, F17 ~func(T16) T17, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17 any](t0 T0, f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13, f14 F14, f15 F15, f16 F16, f17 F17) T17 {
@@ -1316,6 +1435,13 @@ func Unvariadic17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T
}
}
// Unsliced17 converts a function taking a slice parameter into a function with 17 parameters
func Unsliced17[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) R {
return func(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17 T) R {
return f([]T{t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17})
}
}
// Pipe18 takes an initial value t0 and successively applies 18 functions where the input of a function is the return value of the previous function
// The final return value is the result of the last function application
func Pipe18[F1 ~func(T0) T1, F2 ~func(T1) T2, F3 ~func(T2) T3, F4 ~func(T3) T4, F5 ~func(T4) T5, F6 ~func(T5) T6, F7 ~func(T6) T7, F8 ~func(T7) T8, F9 ~func(T8) T9, F10 ~func(T9) T10, F11 ~func(T10) T11, F12 ~func(T11) T12, F13 ~func(T12) T13, F14 ~func(T13) T14, F15 ~func(T14) T15, F16 ~func(T15) T16, F17 ~func(T16) T17, F18 ~func(T17) T18, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18 any](t0 T0, f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13, f14 F14, f15 F15, f16 F16, f17 F17, f18 F18) T18 {
@@ -1419,6 +1545,13 @@ func Unvariadic18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T
}
}
// Unsliced18 converts a function taking a slice parameter into a function with 18 parameters
func Unsliced18[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) R {
return func(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18 T) R {
return f([]T{t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18})
}
}
// Pipe19 takes an initial value t0 and successively applies 19 functions where the input of a function is the return value of the previous function
// The final return value is the result of the last function application
func Pipe19[F1 ~func(T0) T1, F2 ~func(T1) T2, F3 ~func(T2) T3, F4 ~func(T3) T4, F5 ~func(T4) T5, F6 ~func(T5) T6, F7 ~func(T6) T7, F8 ~func(T7) T8, F9 ~func(T8) T9, F10 ~func(T9) T10, F11 ~func(T10) T11, F12 ~func(T11) T12, F13 ~func(T12) T13, F14 ~func(T13) T14, F15 ~func(T14) T15, F16 ~func(T15) T16, F17 ~func(T16) T17, F18 ~func(T17) T18, F19 ~func(T18) T19, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 any](t0 T0, f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13, f14 F14, f15 F15, f16 F16, f17 F17, f18 F18, f19 F19) T19 {
@@ -1525,6 +1658,13 @@ func Unvariadic19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T
}
}
// Unsliced19 converts a function taking a slice parameter into a function with 19 parameters
func Unsliced19[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) R {
return func(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19 T) R {
return f([]T{t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19})
}
}
// Pipe20 takes an initial value t0 and successively applies 20 functions where the input of a function is the return value of the previous function
// The final return value is the result of the last function application
func Pipe20[F1 ~func(T0) T1, F2 ~func(T1) T2, F3 ~func(T2) T3, F4 ~func(T3) T4, F5 ~func(T4) T5, F6 ~func(T5) T6, F7 ~func(T6) T7, F8 ~func(T7) T8, F9 ~func(T8) T9, F10 ~func(T9) T10, F11 ~func(T10) T11, F12 ~func(T11) T12, F13 ~func(T12) T13, F14 ~func(T13) T14, F15 ~func(T14) T15, F16 ~func(T15) T16, F17 ~func(T16) T17, F18 ~func(T17) T18, F19 ~func(T18) T19, F20 ~func(T19) T20, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20 any](t0 T0, f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13, f14 F14, f15 F15, f16 F16, f17 F17, f18 F18, f19 F19, f20 F20) T20 {
@@ -1633,3 +1773,10 @@ func Unvariadic20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T
return f(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, v...)
}
}
// Unsliced20 converts a function taking a slice parameter into a function with 20 parameters
func Unsliced20[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) R {
return func(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20 T) R {
return f([]T{t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20})
}
}

View File

@@ -21,13 +21,13 @@ import (
L "github.com/IBM/fp-go/internal/lazy"
)
// Cache converts a unary function into a unary function that caches the value depending on the parameter
func Cache[F ~func(K) T, K comparable, T any](f F) F {
return ContramapCache[F](func(k K) K { return k })(f)
// Memoize converts a unary function into a unary function that caches the value depending on the parameter
func Memoize[F ~func(K) T, K comparable, T any](f F) F {
return ContramapMemoize[F](func(k K) K { return k })(f)
}
// ContramapCache converts a unary function into a unary function that caches the value depending on the parameter
func ContramapCache[F ~func(A) T, KF func(A) K, A any, K comparable, T any](kf KF) func(F) F {
// ContramapMemoize converts a unary function into a unary function that caches the value depending on the parameter
func ContramapMemoize[F ~func(A) T, KF func(A) K, A any, K comparable, T any](kf KF) func(F) F {
return CacheCallback[F](kf, getOrCreate[K, T]())
}

View File

@@ -0,0 +1,45 @@
// 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 function
import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func fromLibrary(data ...string) string {
return strings.Join(data, "-")
}
func TestUnvariadic(t *testing.T) {
res := Pipe1(
[]string{"A", "B"},
Unvariadic0(fromLibrary),
)
assert.Equal(t, "A-B", res)
}
func TestVariadicArity(t *testing.T) {
f := Unsliced2(Unvariadic0(fromLibrary))
res := f("A", "B")
assert.Equal(t, "A-B", res)
}

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-08-17 22:59:06.2987136 +0200 CEST m=+0.049156901
// 2023-09-12 13:44:24.9409324 +0200 CEST m=+0.008573601
package identity

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-08-17 22:59:08.1313362 +0200 CEST m=+0.111171801
// 2023-09-12 13:44:26.2499883 +0200 CEST m=+0.007601301
package apply

View File

@@ -37,6 +37,24 @@ func MonadTraverse[GA ~[]A, GB ~[]B, A, B, HKTB, HKTAB, HKTRB any](
return MonadTraverseReduce(fof, fmap, fap, ta, f, Append[GB, B], Empty[GB]())
}
/*
*
We need to pass the members of the applicative explicitly, because golang does neither support higher kinded types nor template methods on structs or interfaces
HKTRB = HKT<GB>
HKTB = HKT<B>
HKTAB = HKT<func(A)B>
*/
func MonadTraverseWithIndex[GA ~[]A, GB ~[]B, A, B, HKTB, HKTAB, HKTRB any](
fof func(GB) HKTRB,
fmap func(func(GB) func(B) GB) func(HKTRB) HKTAB,
fap func(HKTB) func(HKTAB) HKTRB,
ta GA,
f func(int, A) HKTB) HKTRB {
return MonadTraverseReduceWithIndex(fof, fmap, fap, ta, f, Append[GB, B], Empty[GB]())
}
func Traverse[GA ~[]A, GB ~[]B, A, B, HKTB, HKTAB, HKTRB any](
fof func(GB) HKTRB,
fmap func(func(GB) func(B) GB) func(HKTRB) HKTAB,
@@ -49,6 +67,18 @@ func Traverse[GA ~[]A, GB ~[]B, A, B, HKTB, HKTAB, HKTRB any](
}
}
func TraverseWithIndex[GA ~[]A, GB ~[]B, A, B, HKTB, HKTAB, HKTRB any](
fof func(GB) HKTRB,
fmap func(func(GB) func(B) GB) func(HKTRB) HKTAB,
fap func(HKTB) func(HKTAB) HKTRB,
f func(int, A) HKTB) func(GA) HKTRB {
return func(ma GA) HKTRB {
return MonadTraverseWithIndex(fof, fmap, fap, ma, f)
}
}
func MonadTraverseReduce[GA ~[]A, GB, A, B, HKTB, HKTAB, HKTRB any](
fof func(GB) HKTRB,
fmap func(func(GB) func(B) GB) func(HKTRB) HKTAB,
@@ -71,6 +101,28 @@ func MonadTraverseReduce[GA ~[]A, GB, A, B, HKTB, HKTAB, HKTRB any](
}, fof(initial))
}
func MonadTraverseReduceWithIndex[GA ~[]A, GB, A, B, HKTB, HKTAB, HKTRB any](
fof func(GB) HKTRB,
fmap func(func(GB) func(B) GB) func(HKTRB) HKTAB,
fap func(HKTB) func(HKTAB) HKTRB,
ta GA,
transform func(int, A) HKTB,
reduce func(GB, B) GB,
initial GB,
) HKTRB {
mmap := fmap(F.Curry2(reduce))
return ReduceWithIndex(ta, func(idx int, r HKTRB, a A) HKTRB {
return F.Pipe2(
r,
mmap,
fap(transform(idx, a)),
)
}, fof(initial))
}
func TraverseReduce[GA ~[]A, GB, A, B, HKTB, HKTAB, HKTRB any](
fof func(GB) HKTRB,
fmap func(func(GB) func(B) GB) func(HKTRB) HKTAB,
@@ -84,3 +136,17 @@ func TraverseReduce[GA ~[]A, GB, A, B, HKTB, HKTAB, HKTRB any](
return MonadTraverseReduce(fof, fmap, fap, ta, transform, reduce, initial)
}
}
func TraverseReduceWithIndex[GA ~[]A, GB, A, B, HKTB, HKTAB, HKTRB any](
fof func(GB) HKTRB,
fmap func(func(GB) func(B) GB) func(HKTRB) HKTAB,
fap func(HKTB) func(HKTAB) HKTRB,
transform func(int, A) HKTB,
reduce func(GB, B) GB,
initial GB,
) func(GA) HKTRB {
return func(ta GA) HKTRB {
return MonadTraverseReduceWithIndex(fof, fmap, fap, ta, transform, reduce, initial)
}
}

View File

@@ -22,6 +22,16 @@ import (
FC "github.com/IBM/fp-go/internal/functor"
)
func MonadAlt[LAZY ~func() HKTFA, E, A, HKTFA any](
fof func(ET.Either[E, A]) HKTFA,
fchain func(HKTFA, func(ET.Either[E, A]) HKTFA) HKTFA,
first HKTFA,
second LAZY) HKTFA {
return fchain(first, ET.Fold(F.Ignore1of1[E](second), F.Flow2(ET.Of[E, A], fof)))
}
// HKTFA = HKT<F, Either<E, A>>
// HKTFB = HKT<F, Either<E, B>>
func MonadMap[E, A, B, HKTFA, HKTFB any](fmap func(HKTFA, func(ET.Either[E, A]) ET.Either[E, B]) HKTFB, fa HKTFA, f func(A) B) HKTFB {

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-08-17 22:59:10.1040409 +0200 CEST m=+0.089470201
// 2023-09-12 13:44:27.9813739 +0200 CEST m=+0.011088001
package io

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-08-17 22:59:10.1132645 +0200 CEST m=+0.098693801
// 2023-09-12 13:44:27.9813739 +0200 CEST m=+0.011088001
package generic
import (

View File

@@ -42,6 +42,16 @@ func TraverseArray[GB ~func() B, GBS ~func() BBS, AAS ~[]A, BBS ~[]B, A, B any](
)
}
func TraverseArrayWithIndex[GB ~func() B, GBS ~func() BBS, AAS ~[]A, BBS ~[]B, A, B any](f func(int, A) GB) func(AAS) GBS {
return RA.TraverseWithIndex[AAS](
Of[GBS, BBS],
Map[GBS, func() func(B) BBS, BBS, func(B) BBS],
Ap[GBS, func() func(B) BBS, GB],
f,
)
}
func SequenceArray[GA ~func() A, GAS ~func() AAS, AAS ~[]A, GAAS ~[]GA, A any](tas GAAS) GAS {
return MonadTraverseArray[GA, GAS](tas, F.Identity[GA])
}
@@ -66,6 +76,16 @@ func TraverseRecord[GB ~func() B, GBS ~func() MB, MA ~map[K]A, MB ~map[K]B, K co
)
}
// TraverseRecordWithIndex transforms a record using an IO transform an IO of a record
func TraverseRecordWithIndex[GB ~func() B, GBS ~func() MB, MA ~map[K]A, MB ~map[K]B, K comparable, A, B any](f func(K, A) GB) func(MA) GBS {
return RR.TraverseWithIndex[MA](
Of[GBS, MB],
Map[GBS, func() func(B) MB, MB, func(B) MB],
Ap[GBS, func() func(B) MB, GB],
f,
)
}
func SequenceRecord[GA ~func() A, GAS ~func() AAS, AAS ~map[K]A, GAAS ~map[K]GA, K comparable, A any](tas GAAS) GAS {
return MonadTraverseRecord[GA, GAS](tas, F.Identity[GA])
}

View File

@@ -29,6 +29,12 @@ func TraverseArray[A, B any](f func(A) IO[B]) func([]A) IO[[]B] {
return G.TraverseArray[IO[B], IO[[]B], []A](f)
}
// TraverseArrayWithIndex applies a function returning an [IO] to all elements in an array and the
// transforms this into an [IO] of that array
func TraverseArrayWithIndex[A, B any](f func(int, A) IO[B]) func([]A) IO[[]B] {
return G.TraverseArrayWithIndex[IO[B], IO[[]B], []A](f)
}
// SequenceArray converts an array of [IO] to an [IO] of an array
func SequenceArray[A any](tas []IO[A]) IO[[]A] {
return G.SequenceArray[IO[A], IO[[]A]](tas)
@@ -38,12 +44,18 @@ func MonadTraverseRecord[K comparable, A, B any](tas map[K]A, f func(A) IO[B]) I
return G.MonadTraverseRecord[IO[B], IO[map[K]B]](tas, f)
}
// TraverseArray applies a function returning an [IO] to all elements in a record and the
// TraverseRecord applies a function returning an [IO] to all elements in a record and the
// transforms this into an [IO] of that record
func TraverseRecord[K comparable, A, B any](f func(A) IO[B]) func(map[K]A) IO[map[K]B] {
return G.TraverseRecord[IO[B], IO[map[K]B], map[K]A](f)
}
// TraverseRecordWithIndex applies a function returning an [IO] to all elements in a record and the
// transforms this into an [IO] of that record
func TraverseRecordWithIndex[K comparable, A, B any](f func(K, A) IO[B]) func(map[K]A) IO[map[K]B] {
return G.TraverseRecordWithIndex[IO[B], IO[map[K]B], map[K]A](f)
}
// SequenceRecord converts a record of [IO] to an [IO] of a record
func SequenceRecord[K comparable, A any](tas map[K]IO[A]) IO[map[K]A] {
return G.SequenceRecord[IO[A], IO[map[K]A]](tas)

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-08-17 22:59:12.0033119 +0200 CEST m=+0.096740401
// 2023-09-12 13:44:29.4935658 +0200 CEST m=+0.015377401
package ioeither

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-08-17 22:59:12.0246635 +0200 CEST m=+0.118092001
// 2023-09-12 13:44:29.4935658 +0200 CEST m=+0.015377401
package generic
import (

View File

@@ -290,3 +290,17 @@ func FromImpure[GA ~func() ET.Either[E, any], IMP ~func(), E any](f IMP) GA {
func Defer[GEA ~func() ET.Either[E, A], E, A any](gen func() GEA) GEA {
return IO.Defer[GEA](gen)
}
func MonadAlt[LAZY ~func() GIOA, GIOA ~func() ET.Either[E, A], E, A any](first GIOA, second LAZY) GIOA {
return eithert.MonadAlt(
IO.Of[GIOA],
IO.MonadChain[GIOA, GIOA],
first,
second,
)
}
func Alt[LAZY ~func() GIOA, GIOA ~func() ET.Either[E, A], E, A any](second LAZY) func(GIOA) GIOA {
return F.Bind2nd(MonadAlt[LAZY], second)
}

View File

@@ -0,0 +1,54 @@
// 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 generic
import (
ET "github.com/IBM/fp-go/either"
M "github.com/IBM/fp-go/monoid"
)
func ApplicativeMonoid[GEA ~func() ET.Either[E, A], GEFA ~func() ET.Either[E, func(A) A], E, A any](
m M.Monoid[A],
) M.Monoid[GEA] {
return M.ApplicativeMonoid(
MonadOf[GEA],
MonadMap[GEA, GEFA],
MonadAp[GEA, GEFA, GEA],
m,
)
}
func ApplicativeMonoidSeq[GEA ~func() ET.Either[E, A], GEFA ~func() ET.Either[E, func(A) A], E, A any](
m M.Monoid[A],
) M.Monoid[GEA] {
return M.ApplicativeMonoid(
MonadOf[GEA],
MonadMap[GEA, GEFA],
MonadApSeq[GEA, GEFA, GEA],
m,
)
}
func ApplicativeMonoidPar[GEA ~func() ET.Either[E, A], GEFA ~func() ET.Either[E, func(A) A], E, A any](
m M.Monoid[A],
) M.Monoid[GEA] {
return M.ApplicativeMonoid(
MonadOf[GEA],
MonadMap[GEA, GEFA],
MonadApPar[GEA, GEFA, GEA],
m,
)
}

View File

@@ -0,0 +1,27 @@
// 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 generic
import (
ET "github.com/IBM/fp-go/either"
S "github.com/IBM/fp-go/semigroup"
)
func AltSemigroup[GIOA ~func() ET.Either[E, A], E, A any]() S.Semigroup[GIOA] {
return S.AltSemigroup(
MonadAlt[func() GIOA],
)
}

View File

@@ -45,6 +45,29 @@ func TraverseArray[GB ~func() ET.Either[E, B], GBS ~func() ET.Either[E, BBS], AA
)
}
// MonadTraverseArrayWithIndex transforms an array
func MonadTraverseArrayWithIndex[GB ~func() ET.Either[E, B], GBS ~func() ET.Either[E, BBS], AAS ~[]A, BBS ~[]B, E, A, B any](tas AAS, f func(int, A) GB) GBS {
return RA.MonadTraverseWithIndex[AAS](
Of[GBS, E, BBS],
Map[GBS, func() ET.Either[E, func(B) BBS], E, BBS, func(B) BBS],
Ap[GBS, func() ET.Either[E, func(B) BBS], GB],
tas,
f,
)
}
// TraverseArrayWithIndex transforms an array
func TraverseArrayWithIndex[GB ~func() ET.Either[E, B], GBS ~func() ET.Either[E, BBS], AAS ~[]A, BBS ~[]B, E, A, B any](f func(int, A) GB) func(AAS) GBS {
return RA.TraverseWithIndex[AAS](
Of[GBS, E, BBS],
Map[GBS, func() ET.Either[E, func(B) BBS], E, BBS, func(B) BBS],
Ap[GBS, func() ET.Either[E, func(B) BBS], GB],
f,
)
}
// SequenceArray converts a homogeneous sequence of either into an either of sequence
func SequenceArray[GA ~func() ET.Either[E, A], GAS ~func() ET.Either[E, AAS], AAS ~[]A, GAAS ~[]GA, E, A any](tas GAAS) GAS {
return MonadTraverseArray[GA, GAS](tas, F.Identity[GA])
@@ -73,6 +96,17 @@ func TraverseRecord[GB ~func() ET.Either[E, B], GBS ~func() ET.Either[E, BBS], A
)
}
// TraverseRecordWithIndex transforms an array
func TraverseRecordWithIndex[GB ~func() ET.Either[E, B], GBS ~func() ET.Either[E, BBS], AAS ~map[K]A, BBS ~map[K]B, K comparable, E, A, B any](f func(K, A) GB) func(AAS) GBS {
return RR.TraverseWithIndex[AAS](
Of[GBS, E, BBS],
Map[GBS, func() ET.Either[E, func(B) BBS], E, BBS, func(B) BBS],
Ap[GBS, func() ET.Either[E, func(B) BBS], GB],
f,
)
}
// SequenceRecord converts a homogeneous sequence of either into an either of sequence
func SequenceRecord[GA ~func() ET.Either[E, A], GAS ~func() ET.Either[E, AAS], AAS ~map[K]A, GAAS ~map[K]GA, K comparable, E, A any](tas GAAS) GAS {
return MonadTraverseRecord[GA, GAS](tas, F.Identity[GA])

View File

@@ -19,6 +19,7 @@ import (
ET "github.com/IBM/fp-go/either"
I "github.com/IBM/fp-go/io"
G "github.com/IBM/fp-go/ioeither/generic"
L "github.com/IBM/fp-go/lazy"
O "github.com/IBM/fp-go/option"
)
@@ -186,7 +187,7 @@ func MonadChainFirstIOK[E, A, B any](ma IOEither[E, A], f func(A) I.IO[B]) IOEit
return G.MonadChainFirstIOK(ma, f)
}
// ChainFirsIOKt runs the monad returned by the function but returns the result of the original monad
// ChainFirsIOK runs the monad returned by the function but returns the result of the original monad
func ChainFirstIOK[E, A, B any](f func(A) I.IO[B]) func(IOEither[E, A]) IOEither[E, A] {
return G.ChainFirstIOK[IOEither[E, A]](f)
}
@@ -207,6 +208,16 @@ func FromImpure[E any](f func()) IOEither[E, any] {
}
// Defer creates an IO by creating a brand new IO via a generator function, each time
func Defer[E, A any](gen func() IOEither[E, A]) IOEither[E, A] {
func Defer[E, A any](gen L.Lazy[IOEither[E, A]]) IOEither[E, A] {
return G.Defer[IOEither[E, A]](gen)
}
// MonadAlt identifies an associative operation on a type constructor
func MonadAlt[E, A any](first IOEither[E, A], second L.Lazy[IOEither[E, A]]) IOEither[E, A] {
return G.MonadAlt(first, second)
}
// Alt identifies an associative operation on a type constructor
func Alt[E, A any](second L.Lazy[IOEither[E, A]]) func(IOEither[E, A]) IOEither[E, A] {
return G.Alt(second)
}

42
ioeither/monoid.go Normal file
View File

@@ -0,0 +1,42 @@
// 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 ioeither
import (
G "github.com/IBM/fp-go/ioeither/generic"
M "github.com/IBM/fp-go/monoid"
)
// ApplicativeMonoid returns a [Monoid] that concatenates [IOEither] instances via their applicative
func ApplicativeMonoid[E, A any](
m M.Monoid[A],
) M.Monoid[IOEither[E, A]] {
return G.ApplicativeMonoid[IOEither[E, A], IOEither[E, func(A) A]](m)
}
// ApplicativeMonoid returns a [Monoid] that concatenates [IOEither] instances via their applicative
func ApplicativeMonoidSeq[E, A any](
m M.Monoid[A],
) M.Monoid[IOEither[E, A]] {
return G.ApplicativeMonoidSeq[IOEither[E, A], IOEither[E, func(A) A]](m)
}
// ApplicativeMonoid returns a [Monoid] that concatenates [IOEither] instances via their applicative
func ApplicativeMonoidPar[E, A any](
m M.Monoid[A],
) M.Monoid[IOEither[E, A]] {
return G.ApplicativeMonoid[IOEither[E, A], IOEither[E, func(A) A]](m)
}

42
ioeither/monoid_test.go Normal file
View File

@@ -0,0 +1,42 @@
// 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 ioeither
import (
"fmt"
"testing"
E "github.com/IBM/fp-go/either"
S "github.com/IBM/fp-go/string"
"github.com/stretchr/testify/assert"
)
func TestApplicativeMonoid(t *testing.T) {
m := ApplicativeMonoid[error](S.Monoid)
// good cases
assert.Equal(t, E.Of[error]("ab"), m.Concat(Of[error]("a"), Of[error]("b"))())
assert.Equal(t, E.Of[error]("a"), m.Concat(Of[error]("a"), m.Empty())())
assert.Equal(t, E.Of[error]("b"), m.Concat(m.Empty(), Of[error]("b"))())
// bad cases
e1 := fmt.Errorf("e1")
e2 := fmt.Errorf("e1")
assert.Equal(t, E.Left[string](e1), m.Concat(Left[string](e1), Of[error]("b"))())
assert.Equal(t, E.Left[string](e1), m.Concat(Left[string](e1), Left[string](e2))())
assert.Equal(t, E.Left[string](e2), m.Concat(Of[error]("a"), Left[string](e2))())
}

26
ioeither/semigroup.go Normal file
View File

@@ -0,0 +1,26 @@
// 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 ioeither
import (
G "github.com/IBM/fp-go/ioeither/generic"
S "github.com/IBM/fp-go/semigroup"
)
// AltSemigroup is a [Semigroup] that tries the first item and then the second one using an alternative
func AltSemigroup[E, A any]() S.Semigroup[IOEither[E, A]] {
return G.AltSemigroup[IOEither[E, A]]()
}

View File

@@ -24,6 +24,11 @@ func TraverseArray[E, A, B any](f func(A) IOEither[E, B]) func([]A) IOEither[E,
return G.TraverseArray[IOEither[E, B], IOEither[E, []B], []A](f)
}
// TraverseArrayWithIndex transforms an array
func TraverseArrayWithIndex[E, A, B any](f func(int, A) IOEither[E, B]) func([]A) IOEither[E, []B] {
return G.TraverseArrayWithIndex[IOEither[E, B], IOEither[E, []B], []A](f)
}
// SequenceArray converts a homogeneous sequence of either into an either of sequence
func SequenceArray[E, A any](ma []IOEither[E, A]) IOEither[E, []A] {
return G.SequenceArray[IOEither[E, A], IOEither[E, []A]](ma)
@@ -34,6 +39,11 @@ func TraverseRecord[K comparable, E, A, B any](f func(A) IOEither[E, B]) func(ma
return G.TraverseRecord[IOEither[E, B], IOEither[E, map[K]B], map[K]A](f)
}
// TraverseRecordWithIndex transforms a record
func TraverseRecordWithIndex[K comparable, E, A, B any](f func(K, A) IOEither[E, B]) func(map[K]A) IOEither[E, map[K]B] {
return G.TraverseRecordWithIndex[IOEither[E, B], IOEither[E, map[K]B], map[K]A](f)
}
// SequenceRecord converts a homogeneous sequence of either into an either of sequence
func SequenceRecord[K comparable, E, A any](ma map[K]IOEither[E, A]) IOEither[E, map[K]A] {
return G.SequenceRecord[IOEither[E, A], IOEither[E, map[K]A]](ma)

37
ioeither/traverse_test.go Normal file
View File

@@ -0,0 +1,37 @@
// 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 ioeither
import (
"fmt"
"testing"
A "github.com/IBM/fp-go/array"
E "github.com/IBM/fp-go/either"
"github.com/stretchr/testify/assert"
)
func TestTraverseArray(t *testing.T) {
src := A.From("A", "B")
trfrm := TraverseArrayWithIndex(func(idx int, data string) IOEither[error, string] {
return Of[error](fmt.Sprintf("idx: %d, data: %s", idx, data))
})
assert.Equal(t, E.Of[error](A.From("idx: 0, data: A", "idx: 1, data: B")), trfrm(src)())
}

View File

@@ -24,6 +24,11 @@ func TraverseArray[A, B any](f func(A) IOOption[B]) func([]A) IOOption[[]B] {
return G.TraverseArray[IOOption[B], IOOption[[]B], []A](f)
}
// TraverseArrayWithIndex transforms an array
func TraverseArrayWithIndex[A, B any](f func(int, A) IOOption[B]) func([]A) IOOption[[]B] {
return G.TraverseArrayWithIndex[IOOption[B], IOOption[[]B], []A](f)
}
// SequenceArray converts a homogeneous sequence of either into an either of sequence
func SequenceArray[A any](ma []IOOption[A]) IOOption[[]A] {
return G.SequenceArray[IOOption[A], IOOption[[]A], []IOOption[A], []A, A](ma)

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-08-17 22:59:14.0582736 +0200 CEST m=+0.248503201
// 2023-09-12 13:44:32.1514823 +0200 CEST m=+0.098931001
package iooption

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-08-17 22:59:14.0642289 +0200 CEST m=+0.254458501
// 2023-09-12 13:44:32.1546277 +0200 CEST m=+0.102076401
package generic
import (

View File

@@ -28,6 +28,13 @@ func TraverseArray[TB ~func() O.Option[B], TBS ~func() O.Option[GB], GA ~[]A, GB
)
}
func TraverseArrayWithIndex[TB ~func() O.Option[B], TBS ~func() O.Option[GB], GA ~[]A, GB ~[]B, A, B any](f func(int, A) TB) func(GA) TBS {
return F.Flow2(
I.TraverseArrayWithIndex[TB, func() []O.Option[B], GA](f),
I.Map[func() []O.Option[B], TBS](O.SequenceArrayG[GB, []O.Option[B], B]),
)
}
func SequenceArray[TB ~func() O.Option[B], TBS ~func() O.Option[GB], GA ~[]TB, GB ~[]B, A, B any](ma GA) TBS {
return TraverseArray[TB, TBS, GA](F.Identity[TB])(ma)
}

View File

@@ -0,0 +1,65 @@
// 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 stateless
import (
"testing"
F "github.com/IBM/fp-go/function"
)
func BenchmarkMulti(b *testing.B) {
// run the Fib function b.N times
for n := 0; n < b.N; n++ {
single()
}
}
func single() int64 {
length := 10000
nums := make([]int, 0, length)
for i := 0; i < length; i++ {
nums = append(nums, i+1)
}
return F.Pipe6(
nums,
FromArray[int],
Filter(func(n int) bool {
return n%2 == 0
}),
Map(func(t int) int64 {
return int64(t)
}),
Filter(func(t int64) bool {
n := t
for n/10 != 0 {
if n%10 == 4 {
return false
}
n = n / 10
}
return true
}),
Map(func(t int64) int {
return int(t)
}),
Reduce(func(n int64, r int) int64 {
return n + int64(r)
}, int64(0)),
)
}

View File

@@ -82,6 +82,7 @@ func Map[GV ~func() O.Option[T.Tuple2[GV, V]], GU ~func() O.Option[T.Tuple2[GU,
m,
)
}
m = O.Map(T.Map2(recurse, f))
return recurse

View File

@@ -29,6 +29,12 @@ func TraverseArray[A, B any](f func(A) Lazy[B]) func([]A) Lazy[[]B] {
return G.TraverseArray[Lazy[B], Lazy[[]B], []A](f)
}
// TraverseArrayWithIndex applies a function returning an [IO] to all elements in an array and the
// transforms this into an [IO] of that array
func TraverseArrayWithIndex[A, B any](f func(int, A) Lazy[B]) func([]A) Lazy[[]B] {
return G.TraverseArrayWithIndex[Lazy[B], Lazy[[]B], []A](f)
}
// SequenceArray converts an array of [IO] to an [IO] of an array
func SequenceArray[A any](tas []Lazy[A]) Lazy[[]A] {
return G.SequenceArray[Lazy[A], Lazy[[]A]](tas)
@@ -38,12 +44,18 @@ func MonadTraverseRecord[K comparable, A, B any](tas map[K]A, f func(A) Lazy[B])
return G.MonadTraverseRecord[Lazy[B], Lazy[map[K]B]](tas, f)
}
// TraverseArray applies a function returning an [IO] to all elements in a record and the
// TraverseRecord applies a function returning an [IO] to all elements in a record and the
// transforms this into an [IO] of that record
func TraverseRecord[K comparable, A, B any](f func(A) Lazy[B]) func(map[K]A) Lazy[map[K]B] {
return G.TraverseRecord[Lazy[B], Lazy[map[K]B], map[K]A](f)
}
// TraverseRecord applies a function returning an [IO] to all elements in a record and the
// transforms this into an [IO] of that record
func TraverseRecordWithIndex[K comparable, A, B any](f func(K, A) Lazy[B]) func(map[K]A) Lazy[map[K]B] {
return G.TraverseRecordWithIndex[Lazy[B], Lazy[map[K]B], map[K]A](f)
}
// SequenceRecord converts a record of [IO] to an [IO] of a record
func SequenceRecord[K comparable, A any](tas map[K]Lazy[A]) Lazy[map[K]A] {
return G.SequenceRecord[Lazy[A], Lazy[map[K]A]](tas)

58
monoid/alt.go Normal file
View File

@@ -0,0 +1,58 @@
// 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 monoid
import (
S "github.com/IBM/fp-go/semigroup"
)
func AlternativeMonoid[A, HKTA, HKTFA any](
fof func(A) HKTA,
fmap func(HKTA, func(A) func(A) A) HKTFA,
fap func(HKTFA, HKTA) HKTA,
falt func(HKTA, func() HKTA) HKTA,
m Monoid[A],
) Monoid[HKTA] {
sg := ApplicativeMonoid(fof, fmap, fap, m)
return MakeMonoid(
func(first, second HKTA) HKTA {
snd := func() HKTA { return second }
return falt(sg.Concat(first, second), func() HKTA {
return falt(first, snd)
})
},
sg.Empty(),
)
}
func AltMonoid[HKTA any](
fzero func() HKTA,
falt func(HKTA, func() HKTA) HKTA,
) Monoid[HKTA] {
return MakeMonoid(
S.AltSemigroup(falt).Concat,
fzero(),
)
}

View File

@@ -20,15 +20,15 @@ import (
)
func ApplicativeMonoid[A, HKTA, HKTFA any](
_of func(A) HKTA,
_map func(HKTA, func(A) func(A) A) HKTFA,
_ap func(HKTFA, HKTA) HKTA,
fof func(A) HKTA,
fmap func(HKTA, func(A) func(A) A) HKTFA,
fap func(HKTFA, HKTA) HKTA,
m Monoid[A],
) Monoid[HKTA] {
return MakeMonoid(
S.ApplySemigroup[A](_map, _ap, m).Concat,
_of(m.Empty()),
S.ApplySemigroup[A](fmap, fap, m).Concat,
fof(m.Empty()),
)
}

View File

@@ -67,7 +67,7 @@ func Modify[S, A any](f func(A) A) func(Iso[S, A]) func(S) S {
}
// Wrap wraps the value
func Unwrap[S, A any](s S) func(Iso[S, A]) A {
func Unwrap[A, S any](s S) func(Iso[S, A]) A {
return func(sa Iso[S, A]) A {
return sa.Get(s)
}
@@ -81,8 +81,8 @@ func Wrap[S, A any](a A) func(Iso[S, A]) S {
}
// From wraps the value
func To[S, A any](s S) func(Iso[S, A]) A {
return Unwrap[S, A](s)
func To[A, S any](s S) func(Iso[S, A]) A {
return Unwrap[A, S](s)
}
// To unwraps the value

View File

@@ -121,7 +121,7 @@ func Compose[S, A, B any](ab Lens[A, B]) func(Lens[S, A]) Lens[S, B] {
// the getter returns an `Option[B]` because the container `A` could already be an option
// if the setter is invoked with `Some[B]` then the value of `B` will be set, potentially on a default value of `A` if `A` did not exist
// if the setter is invoked with `None[B]` then the container `A` is reset to `None[A]` because this is the only way to remove `B`
func ComposeOption[S, A, B any](defaultA A) func(ab Lens[A, B]) func(Lens[S, O.Option[A]]) Lens[S, O.Option[B]] {
func ComposeOption[S, B, A any](defaultA A) func(ab Lens[A, B]) func(Lens[S, O.Option[A]]) Lens[S, O.Option[B]] {
defa := F.Constant(defaultA)
return func(ab Lens[A, B]) func(Lens[S, O.Option[A]]) Lens[S, O.Option[B]] {
foldab := O.Fold(O.None[B], F.Flow2(ab.Get, O.Some[B]))
@@ -172,7 +172,7 @@ func ComposeOption[S, A, B any](defaultA A) func(ab Lens[A, B]) func(Lens[S, O.O
// if the setter is called with `Some[B]` and `A` does not exist, the default of 'A' is updated with `B`
// if the setter is called with `None[B]` and `A` does not exist this is the identity operation on 'S'
// if the setter is called with `None[B]` and `A` does exist, 'B' is removed from 'A'
func ComposeOptions[S, A, B any](defaultA A) func(ab Lens[A, O.Option[B]]) func(Lens[S, O.Option[A]]) Lens[S, O.Option[B]] {
func ComposeOptions[S, B, A any](defaultA A) func(ab Lens[A, O.Option[B]]) func(Lens[S, O.Option[A]]) Lens[S, O.Option[B]] {
defa := F.Constant(defaultA)
noops := F.Constant(F.Identity[S])
noneb := O.None[B]()

View File

@@ -209,7 +209,7 @@ func TestComposeOption(t *testing.T) {
// compose lenses
lens := F.Pipe1(
inner,
ComposeOption[Outer, *Inner, int](defaultInner)(value),
ComposeOption[Outer, int](defaultInner)(value),
)
outer1 := Outer{inner: &Inner{Value: 1, Foo: "a"}}
// the checks
@@ -235,7 +235,7 @@ func TestComposeOptions(t *testing.T) {
// compose lenses
lens := F.Pipe1(
inner,
ComposeOptions[OuterOpt, *InnerOpt, *int](defaultInner)(value),
ComposeOptions[OuterOpt, *int](defaultInner)(value),
)
// additional settings
defaultValue2 := 2

View File

@@ -24,7 +24,7 @@ import (
)
// AtRecord returns a lens that focusses on a value in a record
func AtRecord[M ~map[K]V, K comparable, V any](key K) L.Lens[M, O.Option[V]] {
func AtRecord[M ~map[K]V, V any, K comparable](key K) L.Lens[M, O.Option[V]] {
addKey := F.Bind1of2(RR.UpsertAt[M, K, V])(key)
delKey := F.Bind1of1(RR.DeleteAt[M, K, V])(key)
fold := O.Fold(
@@ -44,6 +44,6 @@ func AtRecord[M ~map[K]V, K comparable, V any](key K) L.Lens[M, O.Option[V]] {
}
// AtKey returns a `Lens` focused on a required key of a `ReadonlyRecord`
func AtKey[M ~map[K]V, S any, K comparable, V any](key K) func(sa L.Lens[S, M]) L.Lens[S, O.Option[V]] {
func AtKey[M ~map[K]V, S any, V any, K comparable](key K) func(sa L.Lens[S, M]) L.Lens[S, O.Option[V]] {
return L.Compose[S](AtRecord[M](key))
}

View File

@@ -22,11 +22,11 @@ import (
)
// AtRecord returns a lens that focusses on a value in a record
func AtRecord[K comparable, V any](key K) L.Lens[map[K]V, O.Option[V]] {
func AtRecord[V any, K comparable](key K) L.Lens[map[K]V, O.Option[V]] {
return G.AtRecord[map[K]V](key)
}
// AtKey returns a `Lens` focused on a required key of a `ReadonlyRecord`
func AtKey[S any, K comparable, V any](key K) func(sa L.Lens[S, map[K]V]) L.Lens[S, O.Option[V]] {
func AtKey[S any, V any, K comparable](key K) func(sa L.Lens[S, map[K]V]) L.Lens[S, O.Option[V]] {
return G.AtKey[map[K]V, S](key)
}

View File

@@ -31,7 +31,7 @@ type (
func TestAtKey(t *testing.T) {
sa := F.Pipe1(
L.Id[S](),
AtKey[S, string, int]("a"),
AtKey[S, int]("a"),
)
assert.Equal(t, O.Some(1), sa.Get(S{"a": 1}))

View File

@@ -198,7 +198,7 @@ func TestOuterLensLaws(t *testing.T) {
eqValue := EQT.Eq[int]()
eqOptValue := O.Eq(eqValue)
// lens to access a value from outer
valueFromOuter := L.ComposeOption[*Outer, *Inner, int](&defaultInner)(valueLens)(outerLens)
valueFromOuter := L.ComposeOption[*Outer, int](&defaultInner)(valueLens)(outerLens)
// try to access the value, this should get an option
assert.True(t, eqOptValue.Equals(valueFromOuter.Get(&emptyOuter), O.None[int]()))
// update the object
@@ -234,7 +234,7 @@ func TestOuterOptLensLaws(t *testing.T) {
valueFromOuter := F.Pipe3(
valueOptLens,
LI.Compose[*InnerOpt](intIso),
L.ComposeOptions[*OuterOpt, *InnerOpt, int](&defaultInnerOpt),
L.ComposeOptions[*OuterOpt, int](&defaultInnerOpt),
I.Ap[L.Lens[*OuterOpt, O.Option[int]]](outerOptLens),
)

View File

@@ -24,6 +24,7 @@ func ApplySemigroup[A any](s S.Semigroup[A]) S.Semigroup[Option[A]] {
return S.ApplySemigroup(MonadMap[A, func(A) A], MonadAp[A, A], s)
}
// ApplicativeMonoid returns a [Monoid] that concatenates [Option] instances via their applicative
func ApplicativeMonoid[A any](m M.Monoid[A]) M.Monoid[Option[A]] {
return M.ApplicativeMonoid(Of[A], MonadMap[A, func(A) A], MonadAp[A, A], m)
}

View File

@@ -36,6 +36,22 @@ func TraverseArray[A, B any](f func(A) Option[B]) func([]A) Option[[]B] {
return TraverseArrayG[[]A, []B](f)
}
// TraverseArrayWithIndexG transforms an array
func TraverseArrayWithIndexG[GA ~[]A, GB ~[]B, A, B any](f func(int, A) Option[B]) func(GA) Option[GB] {
return RA.TraverseWithIndex[GA](
Of[GB],
Map[GB, func(B) GB],
Ap[GB, B],
f,
)
}
// TraverseArrayWithIndex transforms an array
func TraverseArrayWithIndex[A, B any](f func(int, A) Option[B]) func([]A) Option[[]B] {
return TraverseArrayWithIndexG[[]A, []B](f)
}
func SequenceArrayG[GA ~[]A, GOA ~[]Option[A], A any](ma GOA) Option[GA] {
return TraverseArrayG[GOA, GA](F.Identity[Option[A]])(ma)
}

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-08-17 22:59:16.3450991 +0200 CEST m=+0.104894201
// 2023-09-12 13:44:34.2077257 +0200 CEST m=+0.023541001
package option

View File

@@ -20,7 +20,7 @@ import (
RR "github.com/IBM/fp-go/internal/record"
)
// TraverseRecord transforms a record of options into an option of a record
// TraverseRecordG transforms a record of options into an option of a record
func TraverseRecordG[GA ~map[K]A, GB ~map[K]B, K comparable, A, B any](f func(A) Option[B]) func(GA) Option[GB] {
return RR.Traverse[GA](
Of[GB],
@@ -36,6 +36,22 @@ func TraverseRecord[K comparable, A, B any](f func(A) Option[B]) func(map[K]A) O
return TraverseRecordG[map[K]A, map[K]B](f)
}
// TraverseRecordWithIndexG transforms a record of options into an option of a record
func TraverseRecordWithIndexG[GA ~map[K]A, GB ~map[K]B, K comparable, A, B any](f func(K, A) Option[B]) func(GA) Option[GB] {
return RR.TraverseWithIndex[GA](
Of[GB],
Map[GB, func(B) GB],
Ap[GB, B],
f,
)
}
// TraverseRecordWithIndex transforms a record of options into an option of a record
func TraverseRecordWithIndex[K comparable, A, B any](f func(K, A) Option[B]) func(map[K]A) Option[map[K]B] {
return TraverseRecordWithIndexG[map[K]A, map[K]B](f)
}
func SequenceRecordG[GA ~map[K]A, GOA ~map[K]Option[A], K comparable, A any](ma GOA) Option[GA] {
return TraverseRecordG[GOA, GA](F.Identity[Option[A]])(ma)
}

View File

@@ -24,6 +24,11 @@ func TraverseArray[R, A, B any](f func(A) Reader[R, B]) func([]A) Reader[R, []B]
return G.TraverseArray[Reader[R, B], Reader[R, []B], []A](f)
}
// TraverseArrayWithIndex transforms an array
func TraverseArrayWithIndex[R, A, B any](f func(int, A) Reader[R, B]) func([]A) Reader[R, []B] {
return G.TraverseArrayWithIndex[Reader[R, B], Reader[R, []B], []A](f)
}
// SequenceArray converts a homogeneous sequence of either into an either of sequence
func SequenceArray[R, A any](ma []Reader[R, A]) Reader[R, []A] {
return G.SequenceArray[Reader[R, A], Reader[R, []A]](ma)

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-08-17 22:59:18.4448291 +0200 CEST m=+0.161369001
// 2023-09-12 13:44:36.1655251 +0200 CEST m=+0.010000501
package reader

View File

@@ -40,6 +40,16 @@ func TraverseArray[GB ~func(R) B, GBS ~func(R) BBS, AAS ~[]A, BBS ~[]B, R, A, B
)
}
// TraverseArrayWithIndex transforms an array
func TraverseArrayWithIndex[GB ~func(R) B, GBS ~func(R) BBS, AAS ~[]A, BBS ~[]B, R, A, B any](f func(int, A) GB) func(AAS) GBS {
return RA.TraverseWithIndex[AAS](
Of[GBS, R, BBS],
Map[GBS, func(R) func(B) BBS, R, BBS, func(B) BBS],
Ap[GB, GBS, func(R) func(B) BBS, R, B, BBS],
f,
)
}
// SequenceArray converts a homogeneous sequence of either into an either of sequence
func SequenceArray[GA ~func(R) A, GAS ~func(R) AAS, AAS ~[]A, GAAS ~[]GA, R, A any](ma GAAS) GAS {
return MonadTraverseArray[GA, GAS](ma, F.Identity[GA])

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-08-17 22:59:18.5047315 +0200 CEST m=+0.221271401
// 2023-09-12 13:44:36.166526 +0200 CEST m=+0.011001401
package generic
// From0 converts a function with 1 parameters returning a [R] into a function with 0 parameters returning a [GRA]

View File

@@ -24,6 +24,11 @@ func TraverseArray[E, L, A, B any](f func(A) ReaderEither[E, L, B]) func([]A) Re
return G.TraverseArray[ReaderEither[E, L, B], ReaderEither[E, L, []B], []A](f)
}
// TraverseArrayWithIndex transforms an array
func TraverseArrayWithIndex[E, L, A, B any](f func(int, A) ReaderEither[E, L, B]) func([]A) ReaderEither[E, L, []B] {
return G.TraverseArrayWithIndex[ReaderEither[E, L, B], ReaderEither[E, L, []B], []A](f)
}
// SequenceArray converts a homogeneous sequence of either into an either of sequence
func SequenceArray[E, L, A any](ma []ReaderEither[E, L, A]) ReaderEither[E, L, []A] {
return G.SequenceArray[ReaderEither[E, L, A], ReaderEither[E, L, []A]](ma)

View File

@@ -43,6 +43,17 @@ func TraverseArray[GB ~func(E) ET.Either[L, B], GBS ~func(E) ET.Either[L, BBS],
)
}
// TraverseArrayWithIndex transforms an array
func TraverseArrayWithIndex[GB ~func(E) ET.Either[L, B], GBS ~func(E) ET.Either[L, BBS], AAS ~[]A, BBS ~[]B, L, E, A, B any](f func(int, A) GB) func(AAS) GBS {
return RA.TraverseWithIndex[AAS](
Of[GBS, L, E, BBS],
Map[GBS, func(E) ET.Either[L, func(B) BBS], L, E, BBS, func(B) BBS],
Ap[GB, GBS, func(E) ET.Either[L, func(B) BBS], L, E, B, BBS],
f,
)
}
// SequenceArray converts a homogeneous sequence of either into an either of sequence
func SequenceArray[GA ~func(E) ET.Either[L, A], GAS ~func(E) ET.Either[L, AAS], AAS ~[]A, GAAS ~[]GA, L, E, A any](ma GAAS) GAS {
return MonadTraverseArray[GA, GAS](ma, F.Identity[GA])

View File

@@ -25,6 +25,11 @@ func TraverseArray[R, A, B any](f func(A) ReaderIO[R, B]) func([]A) ReaderIO[R,
return G.TraverseArray[ReaderIO[R, B], ReaderIO[R, []B], IO.IO[B], IO.IO[[]B], []A](f)
}
// TraverseArrayWithIndex transforms an array
func TraverseArrayWithIndex[R, A, B any](f func(int, A) ReaderIO[R, B]) func([]A) ReaderIO[R, []B] {
return G.TraverseArrayWithIndex[ReaderIO[R, B], ReaderIO[R, []B], IO.IO[B], IO.IO[[]B], []A](f)
}
// SequenceArray converts a homogeneous sequence of Readers into a Reader of sequence
func SequenceArray[R, A any](ma []ReaderIO[R, A]) ReaderIO[R, []A] {
return G.SequenceArray[ReaderIO[R, A], ReaderIO[R, []A]](ma)

View File

@@ -42,6 +42,17 @@ func TraverseArray[GB ~func(E) GIOB, GBS ~func(E) GIOBS, GIOB ~func() B, GIOBS ~
)
}
// TraverseArrayWithIndex transforms an array
func TraverseArrayWithIndex[GB ~func(E) GIOB, GBS ~func(E) GIOBS, GIOB ~func() B, GIOBS ~func() BBS, AAS ~[]A, BBS ~[]B, E, A, B any](f func(int, A) GB) func(AAS) GBS {
return RA.TraverseWithIndex[AAS](
Of[GBS, GIOBS, E, BBS],
Map[GBS, func(E) func() func(B) BBS, GIOBS, func() func(B) BBS, E, BBS, func(B) BBS],
Ap[GB, GBS, func(E) func() func(B) BBS, GIOB, GIOBS, func() func(B) BBS, E, B, BBS],
f,
)
}
// SequenceArray converts a homogeneous sequence of either into an either of sequence
func SequenceArray[GA ~func(E) GIOA, GAS ~func(E) GIOAS, GIOA ~func() A, GIOAS ~func() AAS, AAS ~[]A, GAAS ~[]GA, E, A any](ma GAAS) GAS {
return MonadTraverseArray[GA, GAS](ma, F.Identity[GA])

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-08-17 22:59:21.3704716 +0200 CEST m=+0.110126101
// 2023-09-12 13:44:37.5566477 +0200 CEST m=+0.009011201
package readerioeither

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-08-17 22:59:21.3811525 +0200 CEST m=+0.120807001
// 2023-09-12 13:44:37.5566477 +0200 CEST m=+0.009011201
package generic
import (

View File

@@ -35,6 +35,20 @@ func MakeReader[GEA ~func(R) GIOA, GIOA ~func() ET.Either[E, A], R, E, A any](f
return f
}
func MonadAlt[LAZY ~func() GEA, GEA ~func(R) GIOA, GIOA ~func() ET.Either[E, A], R, E, A any](first GEA, second LAZY) GEA {
return eithert.MonadAlt(
G.Of[GEA],
G.MonadChain[GEA, GEA],
first,
second,
)
}
func Alt[LAZY ~func() GEA, GEA ~func(R) GIOA, GIOA ~func() ET.Either[E, A], R, E, A any](second LAZY) func(GEA) GEA {
return F.Bind2nd(MonadAlt[LAZY], second)
}
func MonadMap[GEA ~func(R) GIOA, GEB ~func(R) GIOB, GIOA ~func() ET.Either[E, A], GIOB ~func() ET.Either[E, B], R, E, A, B any](fa GEA, f func(A) B) GEB {
return eithert.MonadMap(G.MonadMap[GEA, GEB, GIOA, GIOB, R, ET.Either[E, A], ET.Either[E, B]], fa, f)
}

View File

@@ -44,6 +44,17 @@ func TraverseArray[GB ~func(E) GIOB, GBS ~func(E) GIOBS, GIOB ~func() ET.Either[
)
}
// TraverseArrayWithIndex transforms an array
func TraverseArrayWithIndex[GB ~func(E) GIOB, GBS ~func(E) GIOBS, GIOB ~func() ET.Either[L, B], GIOBS ~func() ET.Either[L, BBS], AAS ~[]A, BBS ~[]B, E, L, A, B any](f func(int, A) GB) func(AAS) GBS {
return RA.TraverseWithIndex[AAS](
Of[GBS, GIOBS, E, L, BBS],
Map[GBS, func(E) func() ET.Either[L, func(B) BBS], GIOBS, func() ET.Either[L, func(B) BBS], E, L, BBS, func(B) BBS],
Ap[GB, GBS, func(E) func() ET.Either[L, func(B) BBS], GIOB, GIOBS, func() ET.Either[L, func(B) BBS], E, L, B, BBS],
f,
)
}
// SequenceArray converts a homogeneous sequence of either into an either of sequence
func SequenceArray[GA ~func(E) GIOA, GAS ~func(E) GIOAS, GIOA ~func() ET.Either[L, A], GIOAS ~func() ET.Either[L, AAS], AAS ~[]A, GAAS ~[]GA, E, L, A any](ma GAAS) GAS {
return MonadTraverseArray[GA, GAS](ma, F.Identity[GA])
@@ -61,7 +72,7 @@ func MonadTraverseRecord[GB ~func(C) GIOB, GBS ~func(C) GIOBS, GIOB ~func() ET.E
)
}
// TraverseRecord transforms an array
// TraverseRecord transforms a record
func TraverseRecord[GB ~func(C) GIOB, GBS ~func(C) GIOBS, GIOB ~func() ET.Either[E, B], GIOBS ~func() ET.Either[E, BBS], AAS ~map[K]A, BBS ~map[K]B, K comparable, C, E, A, B any](f func(A) GB) func(AAS) GBS {
return RR.Traverse[AAS](
Of[GBS, GIOBS, C, E, BBS],
@@ -72,6 +83,17 @@ func TraverseRecord[GB ~func(C) GIOB, GBS ~func(C) GIOBS, GIOB ~func() ET.Either
)
}
// TraverseRecordWithIndex transforms a record
func TraverseRecordWithIndex[GB ~func(C) GIOB, GBS ~func(C) GIOBS, GIOB ~func() ET.Either[E, B], GIOBS ~func() ET.Either[E, BBS], AAS ~map[K]A, BBS ~map[K]B, K comparable, C, E, A, B any](f func(K, A) GB) func(AAS) GBS {
return RR.TraverseWithIndex[AAS](
Of[GBS, GIOBS, C, E, BBS],
Map[GBS, func(C) func() ET.Either[E, func(B) BBS], GIOBS, func() ET.Either[E, func(B) BBS], C, E, BBS, func(B) BBS],
Ap[GB, GBS, func(C) func() ET.Either[E, func(B) BBS], GIOB, GIOBS, func() ET.Either[E, func(B) BBS], C, E, B, BBS],
f,
)
}
// SequenceRecord converts a homogeneous sequence of either into an either of sequence
func SequenceRecord[GA ~func(C) GIOA, GAS ~func(C) GIOAS, GIOA ~func() ET.Either[E, A], GIOAS ~func() ET.Either[E, AAS], AAS ~map[K]A, GAAS ~map[K]GA, K comparable, C, E, A any](tas GAAS) GAS {
return MonadTraverseRecord[GA, GAS](tas, F.Identity[GA])

View File

@@ -19,6 +19,7 @@ import (
ET "github.com/IBM/fp-go/either"
"github.com/IBM/fp-go/io"
IOE "github.com/IBM/fp-go/ioeither"
L "github.com/IBM/fp-go/lazy"
O "github.com/IBM/fp-go/option"
RD "github.com/IBM/fp-go/reader"
RE "github.com/IBM/fp-go/readereither"
@@ -245,7 +246,7 @@ func Swap[R, E, A any](val ReaderIOEither[R, E, A]) ReaderIOEither[R, A, E] {
}
// Defer creates an IO by creating a brand new IO via a generator function, each time
func Defer[R, E, A any](gen func() ReaderIOEither[R, E, A]) ReaderIOEither[R, E, A] {
func Defer[R, E, A any](gen L.Lazy[ReaderIOEither[R, E, A]]) ReaderIOEither[R, E, A] {
return G.Defer[ReaderIOEither[R, E, A]](gen)
}
@@ -253,3 +254,13 @@ func Defer[R, E, A any](gen func() ReaderIOEither[R, E, A]) ReaderIOEither[R, E,
func TryCatch[R, E, A any](f func(R) func() (A, error), onThrow func(error) E) ReaderIOEither[R, E, A] {
return G.TryCatch[ReaderIOEither[R, E, A]](f, onThrow)
}
// MonadAlt identifies an associative operation on a type constructor.
func MonadAlt[R, E, A any](first ReaderIOEither[R, E, A], second L.Lazy[ReaderIOEither[R, E, A]]) ReaderIOEither[R, E, A] {
return G.MonadAlt(first, second)
}
// Alt identifies an associative operation on a type constructor.
func Alt[R, E, A any](second L.Lazy[ReaderIOEither[R, E, A]]) func(ReaderIOEither[R, E, A]) ReaderIOEither[R, E, A] {
return G.Alt(second)
}

View File

@@ -25,6 +25,11 @@ func TraverseArray[R, E, A, B any](f func(A) ReaderIOEither[R, E, B]) func([]A)
return G.TraverseArray[ReaderIOEither[R, E, B], ReaderIOEither[R, E, []B], IOE.IOEither[E, B], IOE.IOEither[E, []B], []A](f)
}
// TraverseArrayWithIndex transforms an array
func TraverseArrayWithIndex[R, E, A, B any](f func(int, A) ReaderIOEither[R, E, B]) func([]A) ReaderIOEither[R, E, []B] {
return G.TraverseArrayWithIndex[ReaderIOEither[R, E, B], ReaderIOEither[R, E, []B], IOE.IOEither[E, B], IOE.IOEither[E, []B], []A](f)
}
// SequenceArray converts a homogeneous sequence of Readers into a Reader of a sequence
func SequenceArray[R, E, A any](ma []ReaderIOEither[R, E, A]) ReaderIOEither[R, E, []A] {
return G.SequenceArray[ReaderIOEither[R, E, A], ReaderIOEither[R, E, []A]](ma)
@@ -35,6 +40,11 @@ func TraverseRecord[R any, K comparable, E, A, B any](f func(A) ReaderIOEither[R
return G.TraverseRecord[ReaderIOEither[R, E, B], ReaderIOEither[R, E, map[K]B], IOE.IOEither[E, B], IOE.IOEither[E, map[K]B], map[K]A](f)
}
// TraverseRecordWithIndex transforms an array
func TraverseRecordWithIndex[R any, K comparable, E, A, B any](f func(K, A) ReaderIOEither[R, E, B]) func(map[K]A) ReaderIOEither[R, E, map[K]B] {
return G.TraverseRecordWithIndex[ReaderIOEither[R, E, B], ReaderIOEither[R, E, map[K]B], IOE.IOEither[E, B], IOE.IOEither[E, map[K]B], map[K]A](f)
}
// SequenceRecord converts a homogeneous sequence of Readers into a Reader of a sequence
func SequenceRecord[R any, K comparable, E, A any](ma map[K]ReaderIOEither[R, E, A]) ReaderIOEither[R, E, map[K]A] {
return G.SequenceRecord[ReaderIOEither[R, E, A], ReaderIOEither[R, E, map[K]A]](ma)

View File

@@ -74,9 +74,7 @@ func TestMultipleHttpRequests(t *testing.T) {
assert.Equal(t, E.Of[error](count), result())
}
// TestHeterogeneousHttpRequests shows how to execute multiple HTTP requests in parallel when
// the response structure of these requests is different. We use [R.TraverseTuple2] to account for the different types
func TestHeterogeneousHttpRequests(t *testing.T) {
func heterogeneousHttpRequests() R.ReaderIOEither[T.Tuple2[PostItem, CatFact]] {
// prepare the http client
client := H.MakeClient(HTTP.DefaultClient)
// readSinglePost sends a GET request and parses the response as [PostItem]
@@ -84,7 +82,7 @@ func TestHeterogeneousHttpRequests(t *testing.T) {
// readSingleCatFact sends a GET request and parses the response as [CatFact]
readSingleCatFact := H.ReadJson[CatFact](client)
data := F.Pipe3(
return F.Pipe3(
T.MakeTuple2("https://jsonplaceholder.typicode.com/posts/1", "https://catfact.ninja/fact"),
T.Map2(H.MakeGetRequest, H.MakeGetRequest),
R.TraverseTuple2(
@@ -94,7 +92,21 @@ func TestHeterogeneousHttpRequests(t *testing.T) {
R.ChainFirstIOK(IO.Logf[T.Tuple2[PostItem, CatFact]]("Log Result: %v")),
)
}
// TestHeterogeneousHttpRequests shows how to execute multiple HTTP requests in parallel when
// the response structure of these requests is different. We use [R.TraverseTuple2] to account for the different types
func TestHeterogeneousHttpRequests(t *testing.T) {
data := heterogeneousHttpRequests()
result := data(context.Background())
fmt.Println(result())
}
// BenchmarkHeterogeneousHttpRequests shows how to execute multiple HTTP requests in parallel when
// the response structure of these requests is different. We use [R.TraverseTuple2] to account for the different types
func BenchmarkHeterogeneousHttpRequests(b *testing.B) {
heterogeneousHttpRequests()(context.Background())
}

28
semigroup/alt.go Normal file
View File

@@ -0,0 +1,28 @@
// 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 semigroup
func AltSemigroup[HKTA any](
falt func(HKTA, func() HKTA) HKTA,
) Semigroup[HKTA] {
return MakeSemigroup(
func(first, second HKTA) HKTA {
return falt(first, func() HKTA { return second })
},
)
}

View File

@@ -25,14 +25,14 @@ HKTA = HKT<A>
HKTFA = HKT<func(A)A>
*/
func ApplySemigroup[A, HKTA, HKTFA any](
_map func(HKTA, func(A) func(A) A) HKTFA,
_ap func(HKTFA, HKTA) HKTA,
fmap func(HKTA, func(A) func(A) A) HKTFA,
fap func(HKTFA, HKTA) HKTA,
s Semigroup[A],
) Semigroup[HKTA] {
cb := F.Curry2(s.Concat)
return MakeSemigroup(func(first HKTA, second HKTA) HKTA {
return _ap(_map(first, cb), second)
return fap(fmap(first, cb), second)
})
}

41
string/generic/string.go Normal file
View File

@@ -0,0 +1,41 @@
// 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 generic
// ToBytes converts the string to bytes
func ToBytes[T ~string](s T) []byte {
return []byte(s)
}
// ToRunes converts the string to runes
func ToRunes[T ~string](s T) []rune {
return []rune(s)
}
// IsEmpty tests if the string is empty
func IsEmpty[T ~string](s T) bool {
return len(s) == 0
}
// IsNonEmpty tests if the string is not empty
func IsNonEmpty[T ~string](s T) bool {
return len(s) > 0
}
// Size returns the size of the string
func Size[T ~string](s T) int {
return len(s)
}

3
test.bat Normal file
View File

@@ -0,0 +1,3 @@
@echo off
mkdir build 2> NUL
gotip test .\... && go1.20.1 test .\... && go test -v -coverprofile build/cover.out -coverpkg=./... -covermode=atomic .\...

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-08-17 22:59:23.6923568 +0200 CEST m=+0.056359401
// 2023-09-12 13:44:39.7573676 +0200 CEST m=+0.040374701
package tuple
@@ -111,7 +111,7 @@ func MakeTuple1[T1 any](t1 T1) Tuple1[T1] {
return Tuple1[T1]{t1}
}
// Tupled1 converts a function with 1 parameters returning into a function taking a Tuple1
// 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 {
@@ -217,7 +217,7 @@ func MakeTuple2[T1, T2 any](t1 T1, t2 T2) Tuple2[T1, T2] {
return Tuple2[T1, T2]{t1, t2}
}
// Tupled2 converts a function with 2 parameters returning into a function taking a Tuple2
// 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 {
@@ -334,7 +334,7 @@ func MakeTuple3[T1, T2, T3 any](t1 T1, t2 T2, t3 T3) Tuple3[T1, T2, T3] {
return Tuple3[T1, T2, T3]{t1, t2, t3}
}
// Tupled3 converts a function with 3 parameters returning into a function taking a Tuple3
// 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 {
@@ -462,7 +462,7 @@ func MakeTuple4[T1, T2, T3, T4 any](t1 T1, t2 T2, t3 T3, t4 T4) Tuple4[T1, T2, T
return Tuple4[T1, T2, T3, T4]{t1, t2, t3, t4}
}
// Tupled4 converts a function with 4 parameters returning into a function taking a Tuple4
// 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 {
@@ -601,7 +601,7 @@ func MakeTuple5[T1, T2, T3, T4, T5 any](t1 T1, t2 T2, t3 T3, t4 T4, t5 T5) Tuple
return Tuple5[T1, T2, T3, T4, T5]{t1, t2, t3, t4, t5}
}
// Tupled5 converts a function with 5 parameters returning into a function taking a Tuple5
// 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 {
@@ -751,7 +751,7 @@ func MakeTuple6[T1, T2, T3, T4, T5, T6 any](t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t
return Tuple6[T1, T2, T3, T4, T5, T6]{t1, t2, t3, t4, t5, t6}
}
// Tupled6 converts a function with 6 parameters returning into a function taking a Tuple6
// 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 {
@@ -912,7 +912,7 @@ func MakeTuple7[T1, T2, T3, T4, T5, T6, T7 any](t1 T1, t2 T2, t3 T3, t4 T4, t5 T
return Tuple7[T1, T2, T3, T4, T5, T6, T7]{t1, t2, t3, t4, t5, t6, t7}
}
// Tupled7 converts a function with 7 parameters returning into a function taking a Tuple7
// 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 {
@@ -1084,7 +1084,7 @@ func MakeTuple8[T1, T2, T3, T4, T5, T6, T7, T8 any](t1 T1, t2 T2, t3 T3, t4 T4,
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 returning into a function taking a Tuple8
// 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 {
@@ -1267,7 +1267,7 @@ func MakeTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t1 T1, t2 T2, t3 T3, t4
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 returning into a function taking a Tuple9
// 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 {
@@ -1461,7 +1461,7 @@ func MakeTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t1 T1, t2 T2, t3 T
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 returning into a function taking a Tuple10
// 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 {

View File

@@ -21,10 +21,12 @@ func Of[T1 any](t T1) Tuple1[T1] {
return MakeTuple1(t)
}
// First returns the first element of a [Tuple2]
func First[T1, T2 any](t Tuple2[T1, T2]) T1 {
return t.F1
}
// Second returns the second element of a [Tuple2]
func Second[T1, T2 any](t Tuple2[T1, T2]) T2 {
return t.F2
}