mirror of
https://github.com/IBM/fp-go.git
synced 2025-08-24 19:29:11 +02:00
Compare commits
101 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
1cdca552b2 | ||
|
73480ca030 | ||
|
734e2b0055 | ||
|
4c28859e89 | ||
|
a516849c07 | ||
|
29200d34dc | ||
|
7a3989989b | ||
|
6a6d53f025 | ||
|
078da752cd | ||
|
1a489fde27 | ||
|
a135b2acae | ||
|
9e9dfa1f5f | ||
|
dd87ea12b3 | ||
|
5fc0d18c97 | ||
|
76c1297576 | ||
|
68aeb4c725 | ||
|
53f3fa1828 | ||
|
97e1e4d92d | ||
|
ec57d5cd4a | ||
|
0ae5b43724 | ||
|
e73e14c0ae | ||
|
325bc376f9 | ||
|
f646ace9fe | ||
|
9f8161fbc1 | ||
|
1c4f2c0403 | ||
|
3b3b80aed0 | ||
|
fdff4e4735 | ||
|
391754e5a6 | ||
|
598a7b261b | ||
|
f0f1a48965 | ||
|
e39e5e0920 | ||
|
9c7a5bb24b | ||
|
89bda4f500 | ||
|
15dffb3256 | ||
|
95fbd93696 | ||
|
6e0d5704bc | ||
|
0aa95e656b | ||
|
b3544a32fc | ||
|
9ad9b4a9bf | ||
|
74763bdadc | ||
|
9aa2ae041f | ||
|
d356fa3c89 | ||
|
f61507254d | ||
|
85f8071c75 | ||
|
76ae6f2bec | ||
|
f4f4fb306c | ||
|
747f477a96 | ||
|
045f4e8849 | ||
|
65e09e0e90 | ||
|
6ab6ff094b | ||
|
e6e35d643c | ||
|
01d490b710 | ||
|
01786a054b | ||
|
d0e4984b60 | ||
|
51ed1693a5 | ||
|
0afedbd7fe | ||
|
3f1bde219a | ||
|
6f91e91eb9 | ||
|
9f6b6d4968 | ||
|
79652d8474 | ||
|
a774d63e66 | ||
|
d86cf55a3d | ||
|
8150ae2a68 | ||
|
7daf65effc | ||
|
909f7c3bce | ||
|
5f0c644c6d | ||
|
9b3d9c6930 | ||
|
59381c1e50 | ||
|
358573cc20 | ||
|
e166806d1b | ||
|
02ec50c91d | ||
|
9e04974d0e | ||
|
2f99ca471a | ||
|
3e09a19d68 | ||
|
839ef47054 | ||
|
144b27233b | ||
|
668eb85aea | ||
|
b077fed094 | ||
|
7d3759619c | ||
|
c73467caf5 | ||
|
ca606767f3 | ||
|
fb82af9a69 | ||
|
57ad8c6466 | ||
|
5a9f405362 | ||
|
89c34254a9 | ||
|
a14feff1d6 | ||
|
f3642bad60 | ||
|
997627b318 | ||
|
1e1411c003 | ||
|
9ed9f8a171 | ||
|
e7428549e4 | ||
|
aef0048119 | ||
|
709d74b135 | ||
|
38c6541254 | ||
|
813b83b423 | ||
|
9139dedbbe | ||
|
5e15119653 | ||
|
986aa21055 | ||
|
3a4c46ec1e | ||
|
96c3ee20ff | ||
|
7af9acfd99 |
12
.github/workflows/build.yml
vendored
12
.github/workflows/build.yml
vendored
@@ -17,8 +17,8 @@ on:
|
||||
env:
|
||||
# Currently no way to detect automatically
|
||||
DEFAULT_BRANCH: main
|
||||
GO_VERSION: 1.20.6 # renovate: datasource=golang-version depName=golang
|
||||
NODE_VERSION: 18
|
||||
GO_VERSION: 1.21.6 # renovate: datasource=golang-version depName=golang
|
||||
NODE_VERSION: 22
|
||||
DRY_RUN: true
|
||||
|
||||
jobs:
|
||||
@@ -26,10 +26,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [ '1.20.x', '1.21.x' ]
|
||||
go-version: [ '1.20.x', '1.21.x', '1.22.x', '1.23.x']
|
||||
steps:
|
||||
# full checkout for semantic-release
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up go ${{ matrix.go-version }}
|
||||
@@ -55,12 +55,12 @@ jobs:
|
||||
steps:
|
||||
# full checkout for semantic-release
|
||||
- name: Full checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Node.js ${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,3 +1,5 @@
|
||||
fp-go.exe
|
||||
fp-go
|
||||
main.exe
|
||||
build/
|
||||
build/
|
||||
.idea
|
16
README.md
16
README.md
@@ -29,9 +29,9 @@ This library aims to provide a set of data types and functions that make it easy
|
||||
|
||||
### How does this play with the [🧘🏽 Zen Of Go](https://the-zen-of-go.netlify.app/)?
|
||||
|
||||
#### 🧘🏽 Each package fulfils a single purpose
|
||||
#### 🧘🏽 Each package fulfills a single purpose
|
||||
|
||||
✔️ Each of the top level packages (e.g. Option, Either, ReaderIOEither, ...) fulfils the purpose of defining the respective data type and implementing the set of common operations for this data type.
|
||||
✔️ Each of the top level packages (e.g. Option, Either, ReaderIOEither, ...) fulfills the purpose of defining the respective data type and implementing the set of common operations for this data type.
|
||||
|
||||
#### 🧘🏽 Handle errors explicitly
|
||||
|
||||
@@ -199,9 +199,9 @@ For that reason these implementations are kept in the `internal` package. These
|
||||
|
||||
The following table lists the relationship between some selected operators
|
||||
|
||||
| Opertator | Parameter | Monad | Result |
|
||||
| -------- | ---------------- | --------------- | -------- |
|
||||
| Map | `func(A) B` | `HKT[A]` | `HKT[B]` |
|
||||
| Chain | `func(A) HKT[B]` | `HKT[A]` | `HKT[B]` |
|
||||
| Ap | `HKT[A]` | `HKT[func(A)B]` | `HKT[B]` |
|
||||
| Flap | `A` | `HKT[func(A)B]` | `HKT[B]` |
|
||||
| Operator | Parameter | Monad | Result |
|
||||
| -------- | ---------------- | --------------- | -------- |
|
||||
| Map | `func(A) B` | `HKT[A]` | `HKT[B]` |
|
||||
| Chain | `func(A) HKT[B]` | `HKT[A]` | `HKT[B]` |
|
||||
| Ap | `HKT[A]` | `HKT[func(A)B]` | `HKT[B]` |
|
||||
| Flap | `A` | `HKT[func(A)B]` | `HKT[B]` |
|
||||
|
@@ -58,7 +58,7 @@ func MapWithIndex[A, B any](f func(int, A) B) func([]A) []B {
|
||||
}
|
||||
|
||||
func Map[A, B any](f func(a A) B) func([]A) []B {
|
||||
return F.Bind2nd(MonadMap[A, B], f)
|
||||
return G.Map[[]A, []B, A, B](f)
|
||||
}
|
||||
|
||||
func MapRef[A, B any](f func(a *A) B) func([]A) []B {
|
||||
|
66
array/bind.go
Normal file
66
array/bind.go
Normal file
@@ -0,0 +1,66 @@
|
||||
// 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 array
|
||||
|
||||
import (
|
||||
G "github.com/IBM/fp-go/array/generic"
|
||||
)
|
||||
|
||||
// Bind creates an empty context of type [S] to be used with the [Bind] operation
|
||||
func Do[S any](
|
||||
empty S,
|
||||
) []S {
|
||||
return G.Do[[]S, S](empty)
|
||||
}
|
||||
|
||||
// Bind attaches the result of a computation to a context [S1] to produce a context [S2]
|
||||
func Bind[S1, S2, T any](
|
||||
setter func(T) func(S1) S2,
|
||||
f func(S1) []T,
|
||||
) func([]S1) []S2 {
|
||||
return G.Bind[[]S1, []S2, []T, S1, S2, T](setter, f)
|
||||
}
|
||||
|
||||
// Let attaches the result of a computation to a context [S1] to produce a context [S2]
|
||||
func Let[S1, S2, T any](
|
||||
setter func(T) func(S1) S2,
|
||||
f func(S1) T,
|
||||
) func([]S1) []S2 {
|
||||
return G.Let[[]S1, []S2, S1, S2, T](setter, f)
|
||||
}
|
||||
|
||||
// LetTo attaches the a value to a context [S1] to produce a context [S2]
|
||||
func LetTo[S1, S2, T any](
|
||||
setter func(T) func(S1) S2,
|
||||
b T,
|
||||
) func([]S1) []S2 {
|
||||
return G.LetTo[[]S1, []S2, S1, S2, T](setter, b)
|
||||
}
|
||||
|
||||
// BindTo initializes a new state [S1] from a value [T]
|
||||
func BindTo[S1, T any](
|
||||
setter func(T) S1,
|
||||
) func([]T) []S1 {
|
||||
return G.BindTo[[]S1, []T, S1, T](setter)
|
||||
}
|
||||
|
||||
// ApS attaches a value to a context [S1] to produce a context [S2] by considering the context and the value concurrently
|
||||
func ApS[S1, S2, T any](
|
||||
setter func(T) func(S1) S2,
|
||||
fa []T,
|
||||
) func([]S1) []S2 {
|
||||
return G.ApS[[]S1, []S2, []T, S1, S2, T](setter, fa)
|
||||
}
|
56
array/bind_test.go
Normal file
56
array/bind_test.go
Normal 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 array
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
F "github.com/IBM/fp-go/function"
|
||||
"github.com/IBM/fp-go/internal/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func getLastName(s utils.Initial) []string {
|
||||
return Of("Doe")
|
||||
}
|
||||
|
||||
func getGivenName(s utils.WithLastName) []string {
|
||||
return Of("John")
|
||||
}
|
||||
|
||||
func TestBind(t *testing.T) {
|
||||
|
||||
res := F.Pipe3(
|
||||
Do(utils.Empty),
|
||||
Bind(utils.SetLastName, getLastName),
|
||||
Bind(utils.SetGivenName, getGivenName),
|
||||
Map(utils.GetFullName),
|
||||
)
|
||||
|
||||
assert.Equal(t, res, Of("John Doe"))
|
||||
}
|
||||
|
||||
func TestApS(t *testing.T) {
|
||||
|
||||
res := F.Pipe3(
|
||||
Do(utils.Empty),
|
||||
ApS(utils.SetLastName, Of("Doe")),
|
||||
ApS(utils.SetGivenName, Of("John")),
|
||||
Map(utils.GetFullName),
|
||||
)
|
||||
|
||||
assert.Equal(t, res, Of("John Doe"))
|
||||
}
|
@@ -147,7 +147,7 @@ func MonadMap[GA ~[]A, GB ~[]B, A, B any](as GA, f func(a A) B) GB {
|
||||
}
|
||||
|
||||
func Map[GA ~[]A, GB ~[]B, A, B any](f func(a A) B) func(GA) GB {
|
||||
return F.Bind2nd(MonadMap[GA, GB, A, B], f)
|
||||
return array.Map[GA, GB](f)
|
||||
}
|
||||
|
||||
func MonadMapWithIndex[GA ~[]A, GB ~[]B, A, B any](as GA, f func(int, A) B) GB {
|
||||
@@ -344,7 +344,7 @@ func MonadFlap[FAB ~func(A) B, GFAB ~[]FAB, GB ~[]B, A, B any](fab GFAB, a A) GB
|
||||
}
|
||||
|
||||
func Flap[FAB ~func(A) B, GFAB ~[]FAB, GB ~[]B, A, B any](a A) func(GFAB) GB {
|
||||
return F.Bind2nd(MonadFlap[FAB, GFAB, GB, A, B], a)
|
||||
return FC.Flap(Map[GFAB, GB], a)
|
||||
}
|
||||
|
||||
func Prepend[ENDO ~func(AS) AS, AS []A, A any](head A) ENDO {
|
||||
|
89
array/generic/bind.go
Normal file
89
array/generic/bind.go
Normal file
@@ -0,0 +1,89 @@
|
||||
// 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 (
|
||||
A "github.com/IBM/fp-go/internal/apply"
|
||||
C "github.com/IBM/fp-go/internal/chain"
|
||||
F "github.com/IBM/fp-go/internal/functor"
|
||||
)
|
||||
|
||||
// Bind creates an empty context of type [S] to be used with the [Bind] operation
|
||||
func Do[GS ~[]S, S any](
|
||||
empty S,
|
||||
) GS {
|
||||
return Of[GS](empty)
|
||||
}
|
||||
|
||||
// Bind attaches the result of a computation to a context [S1] to produce a context [S2]
|
||||
func Bind[GS1 ~[]S1, GS2 ~[]S2, GT ~[]T, S1, S2, T any](
|
||||
setter func(T) func(S1) S2,
|
||||
f func(S1) GT,
|
||||
) func(GS1) GS2 {
|
||||
return C.Bind(
|
||||
Chain[GS1, GS2, S1, S2],
|
||||
Map[GT, GS2, T, S2],
|
||||
setter,
|
||||
f,
|
||||
)
|
||||
}
|
||||
|
||||
// Let attaches the result of a computation to a context [S1] to produce a context [S2]
|
||||
func Let[GS1 ~[]S1, GS2 ~[]S2, S1, S2, T any](
|
||||
key func(T) func(S1) S2,
|
||||
f func(S1) T,
|
||||
) func(GS1) GS2 {
|
||||
return F.Let(
|
||||
Map[GS1, GS2, S1, S2],
|
||||
key,
|
||||
f,
|
||||
)
|
||||
}
|
||||
|
||||
// LetTo attaches the a value to a context [S1] to produce a context [S2]
|
||||
func LetTo[GS1 ~[]S1, GS2 ~[]S2, S1, S2, B any](
|
||||
key func(B) func(S1) S2,
|
||||
b B,
|
||||
) func(GS1) GS2 {
|
||||
return F.LetTo(
|
||||
Map[GS1, GS2, S1, S2],
|
||||
key,
|
||||
b,
|
||||
)
|
||||
}
|
||||
|
||||
// BindTo initializes a new state [S1] from a value [T]
|
||||
func BindTo[GS1 ~[]S1, GT ~[]T, S1, T any](
|
||||
setter func(T) S1,
|
||||
) func(GT) GS1 {
|
||||
return C.BindTo(
|
||||
Map[GT, GS1, T, S1],
|
||||
setter,
|
||||
)
|
||||
}
|
||||
|
||||
// ApS attaches a value to a context [S1] to produce a context [S2] by considering the context and the value concurrently
|
||||
func ApS[GS1 ~[]S1, GS2 ~[]S2, GT ~[]T, S1, S2, T any](
|
||||
setter func(T) func(S1) S2,
|
||||
fa GT,
|
||||
) func(GS1) GS2 {
|
||||
return A.ApS(
|
||||
Ap[GS2, []func(T) S2, GT, S2, T],
|
||||
Map[GS1, []func(T) S2, S1, func(T) S2],
|
||||
setter,
|
||||
fa,
|
||||
)
|
||||
}
|
43
array/generic/monad.go
Normal file
43
array/generic/monad.go
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2024 IBM Corp.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package generic
|
||||
|
||||
import (
|
||||
"github.com/IBM/fp-go/internal/monad"
|
||||
)
|
||||
|
||||
type arrayMonad[A, B any, GA ~[]A, GB ~[]B, GAB ~[]func(A) B] struct{}
|
||||
|
||||
func (o *arrayMonad[A, B, GA, GB, GAB]) Of(a A) GA {
|
||||
return Of[GA, A](a)
|
||||
}
|
||||
|
||||
func (o *arrayMonad[A, B, GA, GB, GAB]) Map(f func(A) B) func(GA) GB {
|
||||
return Map[GA, GB, A, B](f)
|
||||
}
|
||||
|
||||
func (o *arrayMonad[A, B, GA, GB, GAB]) Chain(f func(A) GB) func(GA) GB {
|
||||
return Chain[GA, GB, A, B](f)
|
||||
}
|
||||
|
||||
func (o *arrayMonad[A, B, GA, GB, GAB]) Ap(fa GA) func(GAB) GB {
|
||||
return Ap[GB, GAB, GA, B, A](fa)
|
||||
}
|
||||
|
||||
// Monad implements the monadic operations for an array
|
||||
func Monad[A, B any, GA ~[]A, GB ~[]B, GAB ~[]func(A) B]() monad.Monad[A, B, GA, GB, GAB] {
|
||||
return &arrayMonad[A, B, GA, GB, GAB]{}
|
||||
}
|
26
array/monad.go
Normal file
26
array/monad.go
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2024 IBM Corp.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package array
|
||||
|
||||
import (
|
||||
G "github.com/IBM/fp-go/array/generic"
|
||||
"github.com/IBM/fp-go/internal/monad"
|
||||
)
|
||||
|
||||
// Monad returns the monadic operations for an array
|
||||
func Monad[A, B any]() monad.Monad[A, B, []A, []B, []func(A) B] {
|
||||
return G.Monad[A, B, []A, []B, []func(A) B]()
|
||||
}
|
@@ -24,10 +24,10 @@ import (
|
||||
func concat[T any](left, right []T) []T {
|
||||
// some performance checks
|
||||
ll := len(left)
|
||||
lr := len(right)
|
||||
if ll == 0 {
|
||||
return right
|
||||
}
|
||||
lr := len(right)
|
||||
if lr == 0 {
|
||||
return left
|
||||
}
|
||||
|
@@ -44,11 +44,11 @@ func From[A any](first A, data ...A) NonEmptyArray[A] {
|
||||
return buffer
|
||||
}
|
||||
|
||||
func IsEmpty[A any](as NonEmptyArray[A]) bool {
|
||||
func IsEmpty[A any](_ NonEmptyArray[A]) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func IsNonEmpty[A any](as NonEmptyArray[A]) bool {
|
||||
func IsNonEmpty[A any](_ NonEmptyArray[A]) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
|
74
array/testing/laws.go
Normal file
74
array/testing/laws.go
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright (c) 2023 IBM Corp.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package testing
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
RA "github.com/IBM/fp-go/array"
|
||||
EQ "github.com/IBM/fp-go/eq"
|
||||
L "github.com/IBM/fp-go/internal/monad/testing"
|
||||
)
|
||||
|
||||
// AssertLaws asserts the apply monad laws for the array monad
|
||||
func AssertLaws[A, B, C any](t *testing.T,
|
||||
eqa EQ.Eq[A],
|
||||
eqb EQ.Eq[B],
|
||||
eqc EQ.Eq[C],
|
||||
|
||||
ab func(A) B,
|
||||
bc func(B) C,
|
||||
) func(a A) bool {
|
||||
|
||||
return L.AssertLaws(t,
|
||||
RA.Eq(eqa),
|
||||
RA.Eq(eqb),
|
||||
RA.Eq(eqc),
|
||||
|
||||
RA.Of[A],
|
||||
RA.Of[B],
|
||||
RA.Of[C],
|
||||
|
||||
RA.Of[func(A) A],
|
||||
RA.Of[func(A) B],
|
||||
RA.Of[func(B) C],
|
||||
RA.Of[func(func(A) B) B],
|
||||
|
||||
RA.MonadMap[A, A],
|
||||
RA.MonadMap[A, B],
|
||||
RA.MonadMap[A, C],
|
||||
RA.MonadMap[B, C],
|
||||
|
||||
RA.MonadMap[func(B) C, func(func(A) B) func(A) C],
|
||||
|
||||
RA.MonadChain[A, A],
|
||||
RA.MonadChain[A, B],
|
||||
RA.MonadChain[A, C],
|
||||
RA.MonadChain[B, C],
|
||||
|
||||
RA.MonadAp[A, A],
|
||||
RA.MonadAp[B, A],
|
||||
RA.MonadAp[C, B],
|
||||
RA.MonadAp[C, A],
|
||||
|
||||
RA.MonadAp[B, func(A) B],
|
||||
RA.MonadAp[func(A) C, func(A) B],
|
||||
|
||||
ab,
|
||||
bc,
|
||||
)
|
||||
|
||||
}
|
47
array/testing/laws_test.go
Normal file
47
array/testing/laws_test.go
Normal file
@@ -0,0 +1,47 @@
|
||||
// Copyright (c) 2023 IBM Corp.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package testing
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
EQ "github.com/IBM/fp-go/eq"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestMonadLaws(t *testing.T) {
|
||||
// some comparison
|
||||
eqa := EQ.FromStrictEquals[bool]()
|
||||
eqb := EQ.FromStrictEquals[int]()
|
||||
eqc := EQ.FromStrictEquals[string]()
|
||||
|
||||
ab := func(a bool) int {
|
||||
if a {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
bc := func(b int) string {
|
||||
return fmt.Sprintf("value %d", b)
|
||||
}
|
||||
|
||||
laws := AssertLaws(t, eqa, eqb, eqc, ab, bc)
|
||||
|
||||
assert.True(t, laws(true))
|
||||
assert.True(t, laws(false))
|
||||
}
|
@@ -32,20 +32,20 @@ type bounded[T any] struct {
|
||||
b T
|
||||
}
|
||||
|
||||
func (self bounded[T]) Equals(x, y T) bool {
|
||||
return self.e(x, y)
|
||||
func (b bounded[T]) Equals(x, y T) bool {
|
||||
return b.e(x, y)
|
||||
}
|
||||
|
||||
func (self bounded[T]) Compare(x, y T) int {
|
||||
return self.c(x, y)
|
||||
func (b bounded[T]) Compare(x, y T) int {
|
||||
return b.c(x, y)
|
||||
}
|
||||
|
||||
func (self bounded[T]) Top() T {
|
||||
return self.t
|
||||
func (b bounded[T]) Top() T {
|
||||
return b.t
|
||||
}
|
||||
|
||||
func (self bounded[T]) Bottom() T {
|
||||
return self.b
|
||||
func (b bounded[T]) Bottom() T {
|
||||
return b.b
|
||||
}
|
||||
|
||||
// MakeBounded creates an instance of a bounded type
|
||||
|
@@ -15,6 +15,10 @@
|
||||
|
||||
package bytes
|
||||
|
||||
func Empty() []byte {
|
||||
return Monoid.Empty()
|
||||
}
|
||||
|
||||
func ToString(a []byte) string {
|
||||
return string(a)
|
||||
}
|
||||
|
@@ -365,6 +365,70 @@ func generateContextReaderIOEitherEitherize(f, fg *os.File, i int) {
|
||||
fmt.Fprintln(fg, "}")
|
||||
}
|
||||
|
||||
func generateContextReaderIOEitherUneitherize(f, fg *os.File, i int) {
|
||||
// non generic version
|
||||
fmt.Fprintf(f, "\n// Uneitherize%d converts a function with %d parameters returning a [ReaderIOEither[R]] into a function with %d parameters returning a tuple.\n// The first parameter is considered to be the [context.Context].\n", i, i+1, i)
|
||||
fmt.Fprintf(f, "func Uneitherize%d[F ~func(", i)
|
||||
for j := 0; j < i; j++ {
|
||||
if j > 0 {
|
||||
fmt.Fprintf(f, ", ")
|
||||
}
|
||||
fmt.Fprintf(f, "T%d", j)
|
||||
}
|
||||
fmt.Fprintf(f, ") ReaderIOEither[R]")
|
||||
for j := 0; j < i; j++ {
|
||||
fmt.Fprintf(f, ", T%d", j)
|
||||
}
|
||||
fmt.Fprintf(f, ", R any](f F) func(context.Context")
|
||||
for j := 0; j < i; j++ {
|
||||
fmt.Fprintf(f, ", T%d", j)
|
||||
}
|
||||
fmt.Fprintf(f, ") (R, error) {\n")
|
||||
fmt.Fprintf(f, " return G.Uneitherize%d[ReaderIOEither[R]", i)
|
||||
|
||||
fmt.Fprintf(f, ", func(context.Context")
|
||||
for j := 0; j < i; j++ {
|
||||
fmt.Fprintf(f, ", T%d", j)
|
||||
}
|
||||
fmt.Fprintf(f, ")(R, error)](f)\n")
|
||||
fmt.Fprintln(f, "}")
|
||||
|
||||
// generic version
|
||||
fmt.Fprintf(fg, "\n// Uneitherize%d converts a function with %d parameters returning a [GRA] into a function with %d parameters returning a tuple.\n// The first parameter is considered to be the [context.Context].\n", i, i, i)
|
||||
fmt.Fprintf(fg, "func Uneitherize%d[GRA ~func(context.Context) GIOA, F ~func(context.Context", i)
|
||||
for j := 0; j < i; j++ {
|
||||
fmt.Fprintf(fg, ", T%d", j)
|
||||
}
|
||||
fmt.Fprintf(fg, ") (R, error), GIOA ~func() E.Either[error, R]")
|
||||
for j := 0; j < i; j++ {
|
||||
fmt.Fprintf(fg, ", T%d", j)
|
||||
}
|
||||
fmt.Fprintf(fg, ", R any](f func(")
|
||||
for j := 0; j < i; j++ {
|
||||
if j > 0 {
|
||||
fmt.Fprintf(fg, ", ")
|
||||
}
|
||||
fmt.Fprintf(fg, "T%d", j)
|
||||
}
|
||||
fmt.Fprintf(fg, ") GRA) F {\n")
|
||||
|
||||
fmt.Fprintf(fg, " return func(c context.Context")
|
||||
for j := 0; j < i; j++ {
|
||||
fmt.Fprintf(fg, ", t%d T%d", j, j)
|
||||
}
|
||||
fmt.Fprintf(fg, ") (R, error) {\n")
|
||||
fmt.Fprintf(fg, " return E.UnwrapError(f(")
|
||||
for j := 0; j < i; j++ {
|
||||
if j > 0 {
|
||||
fmt.Fprintf(fg, ", ")
|
||||
}
|
||||
fmt.Fprintf(fg, "t%d", j)
|
||||
}
|
||||
fmt.Fprintf(fg, ")(c)())\n")
|
||||
fmt.Fprintf(fg, " }\n")
|
||||
fmt.Fprintf(fg, "}\n")
|
||||
}
|
||||
|
||||
func generateContextReaderIOEitherHelpers(filename string, count int) error {
|
||||
dir, err := os.Getwd()
|
||||
if err != nil {
|
||||
@@ -420,10 +484,12 @@ import (
|
||||
`)
|
||||
|
||||
generateContextReaderIOEitherEitherize(f, fg, 0)
|
||||
generateContextReaderIOEitherUneitherize(f, fg, 0)
|
||||
|
||||
for i := 1; i <= count; i++ {
|
||||
// eitherize
|
||||
generateContextReaderIOEitherEitherize(f, fg, i)
|
||||
generateContextReaderIOEitherUneitherize(f, fg, i)
|
||||
// sequenceT
|
||||
generateContextReaderIOEitherSequenceT("")(f, fg, i)
|
||||
generateContextReaderIOEitherSequenceT("Seq")(f, fg, i)
|
||||
|
11
cli/pipe.go
11
cli/pipe.go
@@ -265,10 +265,15 @@ func generatePipe(f *os.File, i int) {
|
||||
fmt.Fprintf(f, ", f%d F%d", j, j)
|
||||
}
|
||||
fmt.Fprintf(f, ") T%d {\n", i)
|
||||
for j := 1; j <= i; j++ {
|
||||
fmt.Fprintf(f, " t%d := f%d(t%d)\n", j, j, j-1)
|
||||
fmt.Fprintf(f, " return ")
|
||||
for j := i; j >= 1; j-- {
|
||||
fmt.Fprintf(f, "f%d(", j)
|
||||
}
|
||||
fmt.Fprintf(f, " return t%d\n", i)
|
||||
fmt.Fprintf(f, "t0")
|
||||
for j := 1; j <= i; j++ {
|
||||
fmt.Fprintf(f, ")")
|
||||
}
|
||||
fmt.Fprintf(f, "\n")
|
||||
fmt.Fprintln(f, "}")
|
||||
}
|
||||
|
||||
|
@@ -136,6 +136,70 @@ func generateReaderIOEitherEitherize(f, fg *os.File, i int) {
|
||||
fmt.Fprintf(fg, "}\n")
|
||||
}
|
||||
|
||||
func generateReaderIOEitherUneitherize(f, fg *os.File, i int) {
|
||||
// non generic version
|
||||
fmt.Fprintf(f, "\n// Uneitherize%d converts a function with %d parameters returning a [ReaderIOEither[C, error, R]] into a function with %d parameters returning a tuple.\n// The first parameter is considered to be the context [C].\n", i, i+1, i)
|
||||
fmt.Fprintf(f, "func Uneitherize%d[F ~func(", i)
|
||||
for j := 0; j < i; j++ {
|
||||
if j > 0 {
|
||||
fmt.Fprintf(f, ", ")
|
||||
}
|
||||
fmt.Fprintf(f, "T%d", j)
|
||||
}
|
||||
fmt.Fprintf(f, ") ReaderIOEither[C, error, R]")
|
||||
for j := 0; j < i; j++ {
|
||||
fmt.Fprintf(f, ", T%d", j)
|
||||
}
|
||||
fmt.Fprintf(f, ", C, R any](f F) func(C")
|
||||
for j := 0; j < i; j++ {
|
||||
fmt.Fprintf(f, ", T%d", j)
|
||||
}
|
||||
fmt.Fprintf(f, ") (R, error) {\n")
|
||||
fmt.Fprintf(f, " return G.Uneitherize%d[ReaderIOEither[C, error, R]", i)
|
||||
|
||||
fmt.Fprintf(f, ", func(C")
|
||||
for j := 0; j < i; j++ {
|
||||
fmt.Fprintf(f, ", T%d", j)
|
||||
}
|
||||
fmt.Fprintf(f, ")(R, error)](f)\n")
|
||||
fmt.Fprintln(f, "}")
|
||||
|
||||
// generic version
|
||||
fmt.Fprintf(fg, "\n// Uneitherize%d converts a function with %d parameters returning a [GRA] into a function with %d parameters returning a tuple.\n// The first parameter is considered to be the context [C].\n", i, i, i)
|
||||
fmt.Fprintf(fg, "func Uneitherize%d[GRA ~func(C) GIOA, F ~func(C", i)
|
||||
for j := 0; j < i; j++ {
|
||||
fmt.Fprintf(fg, ", T%d", j)
|
||||
}
|
||||
fmt.Fprintf(fg, ") (R, error), GIOA ~func() E.Either[error, R]")
|
||||
for j := 0; j < i; j++ {
|
||||
fmt.Fprintf(fg, ", T%d", j)
|
||||
}
|
||||
fmt.Fprintf(fg, ", C, R any](f func(")
|
||||
for j := 0; j < i; j++ {
|
||||
if j > 0 {
|
||||
fmt.Fprintf(fg, ", ")
|
||||
}
|
||||
fmt.Fprintf(fg, "T%d", j)
|
||||
}
|
||||
fmt.Fprintf(fg, ") GRA) F {\n")
|
||||
|
||||
fmt.Fprintf(fg, " return func(c C")
|
||||
for j := 0; j < i; j++ {
|
||||
fmt.Fprintf(fg, ", t%d T%d", j, j)
|
||||
}
|
||||
fmt.Fprintf(fg, ") (R, error) {\n")
|
||||
fmt.Fprintf(fg, " return E.UnwrapError(f(")
|
||||
for j := 0; j < i; j++ {
|
||||
if j > 0 {
|
||||
fmt.Fprintf(fg, ", ")
|
||||
}
|
||||
fmt.Fprintf(fg, "t%d", j)
|
||||
}
|
||||
fmt.Fprintf(fg, ")(c)())\n")
|
||||
fmt.Fprintf(fg, " }\n")
|
||||
fmt.Fprintf(fg, "}\n")
|
||||
}
|
||||
|
||||
func generateReaderIOEitherHelpers(filename string, count int) error {
|
||||
dir, err := os.Getwd()
|
||||
if err != nil {
|
||||
@@ -197,12 +261,16 @@ import (
|
||||
generateReaderIOEitherFrom(f, fg, 0)
|
||||
// eitherize
|
||||
generateReaderIOEitherEitherize(f, fg, 0)
|
||||
// uneitherize
|
||||
generateReaderIOEitherUneitherize(f, fg, 0)
|
||||
|
||||
for i := 1; i <= count; i++ {
|
||||
// from
|
||||
generateReaderIOEitherFrom(f, fg, i)
|
||||
// eitherize
|
||||
generateReaderIOEitherEitherize(f, fg, i)
|
||||
// uneitherize
|
||||
generateReaderIOEitherUneitherize(f, fg, i)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
15
cli/templates/functions.go
Normal file
15
cli/templates/functions.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package templates
|
||||
|
||||
import (
|
||||
"text/template"
|
||||
|
||||
E "github.com/IBM/fp-go/either"
|
||||
)
|
||||
|
||||
var (
|
||||
templateFunctions = template.FuncMap{}
|
||||
)
|
||||
|
||||
func Parse(name, tmpl string) E.Either[error, *template.Template] {
|
||||
return E.TryCatchError(template.New(name).Funcs(templateFunctions).Parse(tmpl))
|
||||
}
|
40
cli/tuple.go
40
cli/tuple.go
@@ -405,8 +405,6 @@ func generateTupleHelpers(filename string, count int) error {
|
||||
|
||||
fmt.Fprintf(f, `
|
||||
import (
|
||||
"fmt"
|
||||
"encoding/json"
|
||||
M "github.com/IBM/fp-go/monoid"
|
||||
O "github.com/IBM/fp-go/ord"
|
||||
)
|
||||
@@ -457,7 +455,7 @@ func generateTupleMarshal(f *os.File, i int) {
|
||||
fmt.Fprintf(f, "func (t ")
|
||||
writeTupleType(f, "T", i)
|
||||
fmt.Fprintf(f, ") MarshalJSON() ([]byte, error) {\n")
|
||||
fmt.Fprintf(f, " return json.Marshal([]any{")
|
||||
fmt.Fprintf(f, " return tupleMarshalJSON(")
|
||||
// function prototypes
|
||||
for j := 1; j <= i; j++ {
|
||||
if j > 1 {
|
||||
@@ -465,7 +463,7 @@ func generateTupleMarshal(f *os.File, i int) {
|
||||
}
|
||||
fmt.Fprintf(f, "t.F%d", j)
|
||||
}
|
||||
fmt.Fprintf(f, "})\n")
|
||||
fmt.Fprintf(f, ")\n")
|
||||
fmt.Fprintf(f, "}\n")
|
||||
}
|
||||
|
||||
@@ -475,19 +473,12 @@ func generateTupleUnmarshal(f *os.File, i int) {
|
||||
fmt.Fprintf(f, "func (t *")
|
||||
writeTupleType(f, "T", i)
|
||||
fmt.Fprintf(f, ") UnmarshalJSON(data []byte) error {\n")
|
||||
fmt.Fprintf(f, " var tmp []json.RawMessage\n")
|
||||
fmt.Fprintf(f, " if err := json.Unmarshal(data, &tmp); err != nil {return err}\n")
|
||||
fmt.Fprintf(f, " l := len(tmp)\n")
|
||||
// unmarshal fields
|
||||
fmt.Fprintf(f, " return tupleUnmarshalJSON(data")
|
||||
// function prototypes
|
||||
for j := 1; j <= i; j++ {
|
||||
fmt.Fprintf(f, " if l > %d {\n", j-1)
|
||||
fmt.Fprintf(f, " if err := json.Unmarshal(tmp[%d], &t.F%d); err != nil {return err}\n", j-1, j)
|
||||
fmt.Fprintf(f, ", &t.F%d", j)
|
||||
}
|
||||
fmt.Fprintf(f, " ")
|
||||
for j := 1; j <= i; j++ {
|
||||
fmt.Fprintf(f, "}")
|
||||
}
|
||||
fmt.Fprintf(f, "\n return nil\n")
|
||||
fmt.Fprintf(f, ")\n")
|
||||
fmt.Fprintf(f, "}\n")
|
||||
}
|
||||
|
||||
@@ -570,30 +561,13 @@ func generateTupleString(f *os.File, i int) {
|
||||
writeTupleType(f, "T", i)
|
||||
fmt.Fprintf(f, ") String() string {\n")
|
||||
// convert to string
|
||||
fmt.Fprintf(f, " return fmt.Sprintf(\"Tuple%d[", i)
|
||||
for j := 1; j <= i; j++ {
|
||||
if j > 1 {
|
||||
fmt.Fprintf(f, ", ")
|
||||
}
|
||||
fmt.Fprintf(f, "%s", "%T")
|
||||
}
|
||||
fmt.Fprintf(f, "](")
|
||||
for j := 1; j <= i; j++ {
|
||||
if j > 1 {
|
||||
fmt.Fprintf(f, ", ")
|
||||
}
|
||||
fmt.Fprintf(f, "%s", "%v")
|
||||
}
|
||||
fmt.Fprintf(f, ")\", ")
|
||||
fmt.Fprint(f, " return tupleString(")
|
||||
for j := 1; j <= i; j++ {
|
||||
if j > 1 {
|
||||
fmt.Fprintf(f, ", ")
|
||||
}
|
||||
fmt.Fprintf(f, "t.F%d", j)
|
||||
}
|
||||
for j := 1; j <= i; j++ {
|
||||
fmt.Fprintf(f, ", t.F%d", j)
|
||||
}
|
||||
fmt.Fprintf(f, ")\n")
|
||||
fmt.Fprintf(f, "}\n")
|
||||
}
|
||||
|
@@ -37,7 +37,7 @@ func Of[E, A any](m M.Monoid[E]) func(A) Const[E, A] {
|
||||
return F.Constant1[A](Make[E, A](m.Empty()))
|
||||
}
|
||||
|
||||
func MonadMap[E, A, B any](fa Const[E, A], f func(A) B) Const[E, B] {
|
||||
func MonadMap[E, A, B any](fa Const[E, A], _ func(A) B) Const[E, B] {
|
||||
return Make[E, B](fa.value)
|
||||
}
|
||||
|
||||
|
68
context/readereither/bind.go
Normal file
68
context/readereither/bind.go
Normal file
@@ -0,0 +1,68 @@
|
||||
// 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 readereither
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
G "github.com/IBM/fp-go/readereither/generic"
|
||||
)
|
||||
|
||||
// Bind creates an empty context of type [S] to be used with the [Bind] operation
|
||||
func Do[S any](
|
||||
empty S,
|
||||
) ReaderEither[S] {
|
||||
return G.Do[ReaderEither[S], context.Context, error, S](empty)
|
||||
}
|
||||
|
||||
// Bind attaches the result of a computation to a context [S1] to produce a context [S2]
|
||||
func Bind[S1, S2, T any](
|
||||
setter func(T) func(S1) S2,
|
||||
f func(S1) ReaderEither[T],
|
||||
) func(ReaderEither[S1]) ReaderEither[S2] {
|
||||
return G.Bind[ReaderEither[S1], ReaderEither[S2], ReaderEither[T], context.Context, error, S1, S2, T](setter, f)
|
||||
}
|
||||
|
||||
// Let attaches the result of a computation to a context [S1] to produce a context [S2]
|
||||
func Let[S1, S2, T any](
|
||||
setter func(T) func(S1) S2,
|
||||
f func(S1) T,
|
||||
) func(ReaderEither[S1]) ReaderEither[S2] {
|
||||
return G.Let[ReaderEither[S1], ReaderEither[S2], context.Context, error, S1, S2, T](setter, f)
|
||||
}
|
||||
|
||||
// LetTo attaches the a value to a context [S1] to produce a context [S2]
|
||||
func LetTo[S1, S2, T any](
|
||||
setter func(T) func(S1) S2,
|
||||
b T,
|
||||
) func(ReaderEither[S1]) ReaderEither[S2] {
|
||||
return G.LetTo[ReaderEither[S1], ReaderEither[S2], context.Context, error, S1, S2, T](setter, b)
|
||||
}
|
||||
|
||||
// BindTo initializes a new state [S1] from a value [T]
|
||||
func BindTo[S1, T any](
|
||||
setter func(T) S1,
|
||||
) func(ReaderEither[T]) ReaderEither[S1] {
|
||||
return G.BindTo[ReaderEither[S1], ReaderEither[T], context.Context, error, S1, T](setter)
|
||||
}
|
||||
|
||||
// ApS attaches a value to a context [S1] to produce a context [S2] by considering the context and the value concurrently
|
||||
func ApS[S1, S2, T any](
|
||||
setter func(T) func(S1) S2,
|
||||
fa ReaderEither[T],
|
||||
) func(ReaderEither[S1]) ReaderEither[S2] {
|
||||
return G.ApS[ReaderEither[S1], ReaderEither[S2], ReaderEither[T], context.Context, error, S1, S2, T](setter, fa)
|
||||
}
|
58
context/readereither/bind_test.go
Normal file
58
context/readereither/bind_test.go
Normal 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 readereither
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
E "github.com/IBM/fp-go/either"
|
||||
F "github.com/IBM/fp-go/function"
|
||||
"github.com/IBM/fp-go/internal/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func getLastName(s utils.Initial) ReaderEither[string] {
|
||||
return Of("Doe")
|
||||
}
|
||||
|
||||
func getGivenName(s utils.WithLastName) ReaderEither[string] {
|
||||
return Of("John")
|
||||
}
|
||||
|
||||
func TestBind(t *testing.T) {
|
||||
|
||||
res := F.Pipe3(
|
||||
Do(utils.Empty),
|
||||
Bind(utils.SetLastName, getLastName),
|
||||
Bind(utils.SetGivenName, getGivenName),
|
||||
Map(utils.GetFullName),
|
||||
)
|
||||
|
||||
assert.Equal(t, res(context.Background()), E.Of[error]("John Doe"))
|
||||
}
|
||||
|
||||
func TestApS(t *testing.T) {
|
||||
|
||||
res := F.Pipe3(
|
||||
Do(utils.Empty),
|
||||
ApS(utils.SetLastName, Of("Doe")),
|
||||
ApS(utils.SetGivenName, Of("John")),
|
||||
Map(utils.GetFullName),
|
||||
)
|
||||
|
||||
assert.Equal(t, res(context.Background()), E.Of[error]("John Doe"))
|
||||
}
|
67
context/readerioeither/bind.go
Normal file
67
context/readerioeither/bind.go
Normal file
@@ -0,0 +1,67 @@
|
||||
// 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"
|
||||
IOE "github.com/IBM/fp-go/ioeither"
|
||||
)
|
||||
|
||||
// Bind creates an empty context of type [S] to be used with the [Bind] operation
|
||||
func Do[S any](
|
||||
empty S,
|
||||
) ReaderIOEither[S] {
|
||||
return G.Do[ReaderIOEither[S], IOE.IOEither[error, S], S](empty)
|
||||
}
|
||||
|
||||
// Bind attaches the result of a computation to a context [S1] to produce a context [S2]
|
||||
func Bind[S1, S2, T any](
|
||||
setter func(T) func(S1) S2,
|
||||
f func(S1) ReaderIOEither[T],
|
||||
) func(ReaderIOEither[S1]) ReaderIOEither[S2] {
|
||||
return G.Bind[ReaderIOEither[S1], ReaderIOEither[S2], ReaderIOEither[T], IOE.IOEither[error, S1], IOE.IOEither[error, S2], IOE.IOEither[error, T], S1, S2, T](setter, f)
|
||||
}
|
||||
|
||||
// Let attaches the result of a computation to a context [S1] to produce a context [S2]
|
||||
func Let[S1, S2, T any](
|
||||
setter func(T) func(S1) S2,
|
||||
f func(S1) T,
|
||||
) func(ReaderIOEither[S1]) ReaderIOEither[S2] {
|
||||
return G.Let[ReaderIOEither[S1], ReaderIOEither[S2], IOE.IOEither[error, S1], IOE.IOEither[error, S2], S1, S2, T](setter, f)
|
||||
}
|
||||
|
||||
// LetTo attaches the a value to a context [S1] to produce a context [S2]
|
||||
func LetTo[S1, S2, T any](
|
||||
setter func(T) func(S1) S2,
|
||||
b T,
|
||||
) func(ReaderIOEither[S1]) ReaderIOEither[S2] {
|
||||
return G.LetTo[ReaderIOEither[S1], ReaderIOEither[S2], IOE.IOEither[error, S1], IOE.IOEither[error, S2], S1, S2, T](setter, b)
|
||||
}
|
||||
|
||||
// BindTo initializes a new state [S1] from a value [T]
|
||||
func BindTo[S1, T any](
|
||||
setter func(T) S1,
|
||||
) func(ReaderIOEither[T]) ReaderIOEither[S1] {
|
||||
return G.BindTo[ReaderIOEither[S1], ReaderIOEither[T], IOE.IOEither[error, S1], IOE.IOEither[error, T], S1, T](setter)
|
||||
}
|
||||
|
||||
// ApS attaches a value to a context [S1] to produce a context [S2] by considering the context and the value concurrently
|
||||
func ApS[S1, S2, T any](
|
||||
setter func(T) func(S1) S2,
|
||||
fa ReaderIOEither[T],
|
||||
) func(ReaderIOEither[S1]) ReaderIOEither[S2] {
|
||||
return G.ApS[ReaderIOEither[func(T) S2], ReaderIOEither[S1], ReaderIOEither[S2], ReaderIOEither[T], IOE.IOEither[error, func(T) S2], IOE.IOEither[error, S1], IOE.IOEither[error, S2], IOE.IOEither[error, T], S1, S2, T](setter, fa)
|
||||
}
|
58
context/readerioeither/bind_test.go
Normal file
58
context/readerioeither/bind_test.go
Normal 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 readerioeither
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
E "github.com/IBM/fp-go/either"
|
||||
F "github.com/IBM/fp-go/function"
|
||||
"github.com/IBM/fp-go/internal/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func getLastName(s utils.Initial) ReaderIOEither[string] {
|
||||
return Of("Doe")
|
||||
}
|
||||
|
||||
func getGivenName(s utils.WithLastName) ReaderIOEither[string] {
|
||||
return Of("John")
|
||||
}
|
||||
|
||||
func TestBind(t *testing.T) {
|
||||
|
||||
res := F.Pipe3(
|
||||
Do(utils.Empty),
|
||||
Bind(utils.SetLastName, getLastName),
|
||||
Bind(utils.SetGivenName, getGivenName),
|
||||
Map(utils.GetFullName),
|
||||
)
|
||||
|
||||
assert.Equal(t, res(context.Background())(), E.Of[error]("John Doe"))
|
||||
}
|
||||
|
||||
func TestApS(t *testing.T) {
|
||||
|
||||
res := F.Pipe3(
|
||||
Do(utils.Empty),
|
||||
ApS(utils.SetLastName, Of("Doe")),
|
||||
ApS(utils.SetGivenName, Of("John")),
|
||||
Map(utils.GetFullName),
|
||||
)
|
||||
|
||||
assert.Equal(t, res(context.Background())(), E.Of[error]("John Doe"))
|
||||
}
|
@@ -47,5 +47,5 @@ func ExampleReadFile() {
|
||||
fmt.Println(result())
|
||||
|
||||
// Output:
|
||||
// Right[<nil>, string](Carsten)
|
||||
// Right[string](Carsten)
|
||||
}
|
||||
|
@@ -26,7 +26,7 @@ import (
|
||||
func onWriteAll[W io.Writer](data []byte) func(w W) RIOE.ReaderIOEither[[]byte] {
|
||||
return func(w W) RIOE.ReaderIOEither[[]byte] {
|
||||
return F.Pipe1(
|
||||
RIOE.TryCatch(func(ctx context.Context) func() ([]byte, error) {
|
||||
RIOE.TryCatch(func(_ context.Context) func() ([]byte, error) {
|
||||
return func() ([]byte, error) {
|
||||
_, err := w.Write(data)
|
||||
return data, err
|
||||
|
@@ -2,7 +2,7 @@ package readerioeither
|
||||
|
||||
// Code generated by go generate; DO NOT EDIT.
|
||||
// This file was generated by robots at
|
||||
// 2023-10-23 08:30:39.012572 +0200 CEST m=+0.008846101
|
||||
// 2024-05-24 22:24:01.4250895 +0200 CEST m=+0.014515801
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -17,12 +17,24 @@ func Eitherize0[F ~func(context.Context) (R, error), R any](f F) func() ReaderIO
|
||||
return G.Eitherize0[ReaderIOEither[R]](f)
|
||||
}
|
||||
|
||||
// Uneitherize0 converts a function with 1 parameters returning a [ReaderIOEither[R]] into a function with 0 parameters returning a tuple.
|
||||
// The first parameter is considered to be the [context.Context].
|
||||
func Uneitherize0[F ~func() ReaderIOEither[R], R any](f F) func(context.Context) (R, error) {
|
||||
return G.Uneitherize0[ReaderIOEither[R], func(context.Context) (R, error)](f)
|
||||
}
|
||||
|
||||
// Eitherize1 converts a function with 1 parameters returning a tuple into a function with 1 parameters returning a [ReaderIOEither[R]]
|
||||
// The inverse function is [Uneitherize1]
|
||||
func Eitherize1[F ~func(context.Context, T0) (R, error), T0, R any](f F) func(T0) ReaderIOEither[R] {
|
||||
return G.Eitherize1[ReaderIOEither[R]](f)
|
||||
}
|
||||
|
||||
// Uneitherize1 converts a function with 2 parameters returning a [ReaderIOEither[R]] into a function with 1 parameters returning a tuple.
|
||||
// The first parameter is considered to be the [context.Context].
|
||||
func Uneitherize1[F ~func(T0) ReaderIOEither[R], T0, R any](f F) func(context.Context, T0) (R, error) {
|
||||
return G.Uneitherize1[ReaderIOEither[R], func(context.Context, T0) (R, error)](f)
|
||||
}
|
||||
|
||||
// SequenceT1 converts 1 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple1].
|
||||
func SequenceT1[T1 any](t1 ReaderIOEither[T1]) ReaderIOEither[T.Tuple1[T1]] {
|
||||
return G.SequenceT1[ReaderIOEither[T.Tuple1[T1]]](t1)
|
||||
@@ -74,6 +86,12 @@ func Eitherize2[F ~func(context.Context, T0, T1) (R, error), T0, T1, R any](f F)
|
||||
return G.Eitherize2[ReaderIOEither[R]](f)
|
||||
}
|
||||
|
||||
// Uneitherize2 converts a function with 3 parameters returning a [ReaderIOEither[R]] into a function with 2 parameters returning a tuple.
|
||||
// The first parameter is considered to be the [context.Context].
|
||||
func Uneitherize2[F ~func(T0, T1) ReaderIOEither[R], T0, T1, R any](f F) func(context.Context, T0, T1) (R, error) {
|
||||
return G.Uneitherize2[ReaderIOEither[R], func(context.Context, T0, T1) (R, error)](f)
|
||||
}
|
||||
|
||||
// SequenceT2 converts 2 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple2].
|
||||
func SequenceT2[T1, T2 any](t1 ReaderIOEither[T1], t2 ReaderIOEither[T2]) ReaderIOEither[T.Tuple2[T1, T2]] {
|
||||
return G.SequenceT2[ReaderIOEither[T.Tuple2[T1, T2]]](t1, t2)
|
||||
@@ -125,6 +143,12 @@ func Eitherize3[F ~func(context.Context, T0, T1, T2) (R, error), T0, T1, T2, R a
|
||||
return G.Eitherize3[ReaderIOEither[R]](f)
|
||||
}
|
||||
|
||||
// Uneitherize3 converts a function with 4 parameters returning a [ReaderIOEither[R]] into a function with 3 parameters returning a tuple.
|
||||
// The first parameter is considered to be the [context.Context].
|
||||
func Uneitherize3[F ~func(T0, T1, T2) ReaderIOEither[R], T0, T1, T2, R any](f F) func(context.Context, T0, T1, T2) (R, error) {
|
||||
return G.Uneitherize3[ReaderIOEither[R], func(context.Context, T0, T1, T2) (R, error)](f)
|
||||
}
|
||||
|
||||
// SequenceT3 converts 3 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple3].
|
||||
func SequenceT3[T1, T2, T3 any](t1 ReaderIOEither[T1], t2 ReaderIOEither[T2], t3 ReaderIOEither[T3]) ReaderIOEither[T.Tuple3[T1, T2, T3]] {
|
||||
return G.SequenceT3[ReaderIOEither[T.Tuple3[T1, T2, T3]]](t1, t2, t3)
|
||||
@@ -176,6 +200,12 @@ func Eitherize4[F ~func(context.Context, T0, T1, T2, T3) (R, error), T0, T1, T2,
|
||||
return G.Eitherize4[ReaderIOEither[R]](f)
|
||||
}
|
||||
|
||||
// Uneitherize4 converts a function with 5 parameters returning a [ReaderIOEither[R]] into a function with 4 parameters returning a tuple.
|
||||
// The first parameter is considered to be the [context.Context].
|
||||
func Uneitherize4[F ~func(T0, T1, T2, T3) ReaderIOEither[R], T0, T1, T2, T3, R any](f F) func(context.Context, T0, T1, T2, T3) (R, error) {
|
||||
return G.Uneitherize4[ReaderIOEither[R], func(context.Context, T0, T1, T2, T3) (R, error)](f)
|
||||
}
|
||||
|
||||
// SequenceT4 converts 4 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple4].
|
||||
func SequenceT4[T1, T2, T3, T4 any](t1 ReaderIOEither[T1], t2 ReaderIOEither[T2], t3 ReaderIOEither[T3], t4 ReaderIOEither[T4]) ReaderIOEither[T.Tuple4[T1, T2, T3, T4]] {
|
||||
return G.SequenceT4[ReaderIOEither[T.Tuple4[T1, T2, T3, T4]]](t1, t2, t3, t4)
|
||||
@@ -227,6 +257,12 @@ func Eitherize5[F ~func(context.Context, T0, T1, T2, T3, T4) (R, error), T0, T1,
|
||||
return G.Eitherize5[ReaderIOEither[R]](f)
|
||||
}
|
||||
|
||||
// Uneitherize5 converts a function with 6 parameters returning a [ReaderIOEither[R]] into a function with 5 parameters returning a tuple.
|
||||
// The first parameter is considered to be the [context.Context].
|
||||
func Uneitherize5[F ~func(T0, T1, T2, T3, T4) ReaderIOEither[R], T0, T1, T2, T3, T4, R any](f F) func(context.Context, T0, T1, T2, T3, T4) (R, error) {
|
||||
return G.Uneitherize5[ReaderIOEither[R], func(context.Context, T0, T1, T2, T3, T4) (R, error)](f)
|
||||
}
|
||||
|
||||
// SequenceT5 converts 5 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple5].
|
||||
func SequenceT5[T1, T2, T3, T4, T5 any](t1 ReaderIOEither[T1], t2 ReaderIOEither[T2], t3 ReaderIOEither[T3], t4 ReaderIOEither[T4], t5 ReaderIOEither[T5]) ReaderIOEither[T.Tuple5[T1, T2, T3, T4, T5]] {
|
||||
return G.SequenceT5[ReaderIOEither[T.Tuple5[T1, T2, T3, T4, T5]]](t1, t2, t3, t4, t5)
|
||||
@@ -278,6 +314,12 @@ func Eitherize6[F ~func(context.Context, T0, T1, T2, T3, T4, T5) (R, error), T0,
|
||||
return G.Eitherize6[ReaderIOEither[R]](f)
|
||||
}
|
||||
|
||||
// Uneitherize6 converts a function with 7 parameters returning a [ReaderIOEither[R]] into a function with 6 parameters returning a tuple.
|
||||
// The first parameter is considered to be the [context.Context].
|
||||
func Uneitherize6[F ~func(T0, T1, T2, T3, T4, T5) ReaderIOEither[R], T0, T1, T2, T3, T4, T5, R any](f F) func(context.Context, T0, T1, T2, T3, T4, T5) (R, error) {
|
||||
return G.Uneitherize6[ReaderIOEither[R], func(context.Context, T0, T1, T2, T3, T4, T5) (R, error)](f)
|
||||
}
|
||||
|
||||
// SequenceT6 converts 6 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple6].
|
||||
func SequenceT6[T1, T2, T3, T4, T5, T6 any](t1 ReaderIOEither[T1], t2 ReaderIOEither[T2], t3 ReaderIOEither[T3], t4 ReaderIOEither[T4], t5 ReaderIOEither[T5], t6 ReaderIOEither[T6]) ReaderIOEither[T.Tuple6[T1, T2, T3, T4, T5, T6]] {
|
||||
return G.SequenceT6[ReaderIOEither[T.Tuple6[T1, T2, T3, T4, T5, T6]]](t1, t2, t3, t4, t5, t6)
|
||||
@@ -329,6 +371,12 @@ func Eitherize7[F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6) (R, error),
|
||||
return G.Eitherize7[ReaderIOEither[R]](f)
|
||||
}
|
||||
|
||||
// Uneitherize7 converts a function with 8 parameters returning a [ReaderIOEither[R]] into a function with 7 parameters returning a tuple.
|
||||
// The first parameter is considered to be the [context.Context].
|
||||
func Uneitherize7[F ~func(T0, T1, T2, T3, T4, T5, T6) ReaderIOEither[R], T0, T1, T2, T3, T4, T5, T6, R any](f F) func(context.Context, T0, T1, T2, T3, T4, T5, T6) (R, error) {
|
||||
return G.Uneitherize7[ReaderIOEither[R], func(context.Context, T0, T1, T2, T3, T4, T5, T6) (R, error)](f)
|
||||
}
|
||||
|
||||
// SequenceT7 converts 7 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple7].
|
||||
func SequenceT7[T1, T2, T3, T4, T5, T6, T7 any](t1 ReaderIOEither[T1], t2 ReaderIOEither[T2], t3 ReaderIOEither[T3], t4 ReaderIOEither[T4], t5 ReaderIOEither[T5], t6 ReaderIOEither[T6], t7 ReaderIOEither[T7]) ReaderIOEither[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]] {
|
||||
return G.SequenceT7[ReaderIOEither[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]]](t1, t2, t3, t4, t5, t6, t7)
|
||||
@@ -380,6 +428,12 @@ func Eitherize8[F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7) (R, err
|
||||
return G.Eitherize8[ReaderIOEither[R]](f)
|
||||
}
|
||||
|
||||
// Uneitherize8 converts a function with 9 parameters returning a [ReaderIOEither[R]] into a function with 8 parameters returning a tuple.
|
||||
// The first parameter is considered to be the [context.Context].
|
||||
func Uneitherize8[F ~func(T0, T1, T2, T3, T4, T5, T6, T7) ReaderIOEither[R], T0, T1, T2, T3, T4, T5, T6, T7, R any](f F) func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7) (R, error) {
|
||||
return G.Uneitherize8[ReaderIOEither[R], func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7) (R, error)](f)
|
||||
}
|
||||
|
||||
// SequenceT8 converts 8 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple8].
|
||||
func SequenceT8[T1, T2, T3, T4, T5, T6, T7, T8 any](t1 ReaderIOEither[T1], t2 ReaderIOEither[T2], t3 ReaderIOEither[T3], t4 ReaderIOEither[T4], t5 ReaderIOEither[T5], t6 ReaderIOEither[T6], t7 ReaderIOEither[T7], t8 ReaderIOEither[T8]) ReaderIOEither[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]] {
|
||||
return G.SequenceT8[ReaderIOEither[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]](t1, t2, t3, t4, t5, t6, t7, t8)
|
||||
@@ -431,6 +485,12 @@ func Eitherize9[F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8) (R,
|
||||
return G.Eitherize9[ReaderIOEither[R]](f)
|
||||
}
|
||||
|
||||
// Uneitherize9 converts a function with 10 parameters returning a [ReaderIOEither[R]] into a function with 9 parameters returning a tuple.
|
||||
// The first parameter is considered to be the [context.Context].
|
||||
func Uneitherize9[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8) ReaderIOEither[R], T0, T1, T2, T3, T4, T5, T6, T7, T8, R any](f F) func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8) (R, error) {
|
||||
return G.Uneitherize9[ReaderIOEither[R], func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8) (R, error)](f)
|
||||
}
|
||||
|
||||
// SequenceT9 converts 9 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple9].
|
||||
func SequenceT9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t1 ReaderIOEither[T1], t2 ReaderIOEither[T2], t3 ReaderIOEither[T3], t4 ReaderIOEither[T4], t5 ReaderIOEither[T5], t6 ReaderIOEither[T6], t7 ReaderIOEither[T7], t8 ReaderIOEither[T8], t9 ReaderIOEither[T9]) ReaderIOEither[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]] {
|
||||
return G.SequenceT9[ReaderIOEither[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]](t1, t2, t3, t4, t5, t6, t7, t8, t9)
|
||||
@@ -482,6 +542,12 @@ func Eitherize10[F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9
|
||||
return G.Eitherize10[ReaderIOEither[R]](f)
|
||||
}
|
||||
|
||||
// Uneitherize10 converts a function with 11 parameters returning a [ReaderIOEither[R]] into a function with 10 parameters returning a tuple.
|
||||
// The first parameter is considered to be the [context.Context].
|
||||
func Uneitherize10[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) ReaderIOEither[R], T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, R any](f F) func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (R, error) {
|
||||
return G.Uneitherize10[ReaderIOEither[R], func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (R, error)](f)
|
||||
}
|
||||
|
||||
// SequenceT10 converts 10 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple10].
|
||||
func SequenceT10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t1 ReaderIOEither[T1], t2 ReaderIOEither[T2], t3 ReaderIOEither[T3], t4 ReaderIOEither[T4], t5 ReaderIOEither[T5], t6 ReaderIOEither[T6], t7 ReaderIOEither[T7], t8 ReaderIOEither[T8], t9 ReaderIOEither[T9], t10 ReaderIOEither[T10]) ReaderIOEither[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]] {
|
||||
return G.SequenceT10[ReaderIOEither[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]](t1, t2, t3, t4, t5, t6, t7, t8, t9, t10)
|
||||
|
92
context/readerioeither/generic/bind.go
Normal file
92
context/readerioeither/generic/bind.go
Normal file
@@ -0,0 +1,92 @@
|
||||
// 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"
|
||||
A "github.com/IBM/fp-go/internal/apply"
|
||||
C "github.com/IBM/fp-go/internal/chain"
|
||||
F "github.com/IBM/fp-go/internal/functor"
|
||||
)
|
||||
|
||||
// Bind creates an empty context of type [S] to be used with the [Bind] operation
|
||||
func Do[GRS ~func(context.Context) GS, GS ~func() ET.Either[error, S], S any](
|
||||
empty S,
|
||||
) GRS {
|
||||
return Of[GRS, GS, S](empty)
|
||||
}
|
||||
|
||||
// Bind attaches the result of a computation to a context [S1] to produce a context [S2]
|
||||
func Bind[GRS1 ~func(context.Context) GS1, GRS2 ~func(context.Context) GS2, GRT ~func(context.Context) GT, GS1 ~func() ET.Either[error, S1], GS2 ~func() ET.Either[error, S2], GT ~func() ET.Either[error, T], S1, S2, T any](
|
||||
setter func(T) func(S1) S2,
|
||||
f func(S1) GRT,
|
||||
) func(GRS1) GRS2 {
|
||||
return C.Bind(
|
||||
Chain[GRS1, GRS2, GS1, GS2, S1, S2],
|
||||
Map[GRT, GRS2, GT, GS2, T, S2],
|
||||
setter,
|
||||
f,
|
||||
)
|
||||
}
|
||||
|
||||
// Let attaches the result of a computation to a context [S1] to produce a context [S2]
|
||||
func Let[GRS1 ~func(context.Context) GS1, GRS2 ~func(context.Context) GS2, GS1 ~func() ET.Either[error, S1], GS2 ~func() ET.Either[error, S2], S1, S2, T any](
|
||||
key func(T) func(S1) S2,
|
||||
f func(S1) T,
|
||||
) func(GRS1) GRS2 {
|
||||
return F.Let(
|
||||
Map[GRS1, GRS2, GS1, GS2, S1, S2],
|
||||
key,
|
||||
f,
|
||||
)
|
||||
}
|
||||
|
||||
// LetTo attaches the a value to a context [S1] to produce a context [S2]
|
||||
func LetTo[GRS1 ~func(context.Context) GS1, GRS2 ~func(context.Context) GS2, GS1 ~func() ET.Either[error, S1], GS2 ~func() ET.Either[error, S2], S1, S2, B any](
|
||||
key func(B) func(S1) S2,
|
||||
b B,
|
||||
) func(GRS1) GRS2 {
|
||||
return F.LetTo(
|
||||
Map[GRS1, GRS2, GS1, GS2, S1, S2],
|
||||
key,
|
||||
b,
|
||||
)
|
||||
}
|
||||
|
||||
// BindTo initializes a new state [S1] from a value [T]
|
||||
func BindTo[GRS1 ~func(context.Context) GS1, GRT ~func(context.Context) GT, GS1 ~func() ET.Either[error, S1], GT ~func() ET.Either[error, T], S1, T any](
|
||||
setter func(T) S1,
|
||||
) func(GRT) GRS1 {
|
||||
return C.BindTo(
|
||||
Map[GRT, GRS1, GT, GS1, T, S1],
|
||||
setter,
|
||||
)
|
||||
}
|
||||
|
||||
// ApS attaches a value to a context [S1] to produce a context [S2] by considering the context and the value concurrently
|
||||
func ApS[GRTS1 ~func(context.Context) GTS1, GRS1 ~func(context.Context) GS1, GRS2 ~func(context.Context) GS2, GRT ~func(context.Context) GT, GTS1 ~func() ET.Either[error, func(T) S2], GS1 ~func() ET.Either[error, S1], GS2 ~func() ET.Either[error, S2], GT ~func() ET.Either[error, T], S1, S2, T any](
|
||||
setter func(T) func(S1) S2,
|
||||
fa GRT,
|
||||
) func(GRS1) GRS2 {
|
||||
return A.ApS(
|
||||
Ap[GRS2, GRTS1, GRT, GS2, GTS1, GT],
|
||||
Map[GRS1, GRTS1, GS1, GTS1, S1, func(T) S2],
|
||||
setter,
|
||||
fa,
|
||||
)
|
||||
}
|
@@ -2,7 +2,7 @@ package generic
|
||||
|
||||
// Code generated by go generate; DO NOT EDIT.
|
||||
// This file was generated by robots at
|
||||
// 2023-10-23 08:30:39.012572 +0200 CEST m=+0.008846101
|
||||
// 2024-05-24 22:24:01.4250895 +0200 CEST m=+0.014515801
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -19,12 +19,28 @@ func Eitherize0[GRA ~func(context.Context) GIOA, F ~func(context.Context) (R, er
|
||||
return RE.Eitherize0[GRA](f)
|
||||
}
|
||||
|
||||
// Uneitherize0 converts a function with 0 parameters returning a [GRA] into a function with 0 parameters returning a tuple.
|
||||
// The first parameter is considered to be the [context.Context].
|
||||
func Uneitherize0[GRA ~func(context.Context) GIOA, F ~func(context.Context) (R, error), GIOA ~func() E.Either[error, R], R any](f func() GRA) F {
|
||||
return func(c context.Context) (R, error) {
|
||||
return E.UnwrapError(f()(c)())
|
||||
}
|
||||
}
|
||||
|
||||
// Eitherize1 converts a function with 1 parameters returning a tuple into a function with 1 parameters returning a [GRA]
|
||||
// The inverse function is [Uneitherize1]
|
||||
func Eitherize1[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0) (R, error), GIOA ~func() E.Either[error, R], T0, R any](f F) func(T0) GRA {
|
||||
return RE.Eitherize1[GRA](f)
|
||||
}
|
||||
|
||||
// Uneitherize1 converts a function with 1 parameters returning a [GRA] into a function with 1 parameters returning a tuple.
|
||||
// The first parameter is considered to be the [context.Context].
|
||||
func Uneitherize1[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0) (R, error), GIOA ~func() E.Either[error, R], T0, R any](f func(T0) GRA) F {
|
||||
return func(c context.Context, t0 T0) (R, error) {
|
||||
return E.UnwrapError(f(t0)(c)())
|
||||
}
|
||||
}
|
||||
|
||||
// SequenceT1 converts 1 readers into a reader of a [T.Tuple1].
|
||||
func SequenceT1[
|
||||
GR_TUPLE1 ~func(context.Context) GIO_TUPLE1,
|
||||
@@ -169,6 +185,14 @@ func Eitherize2[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1
|
||||
return RE.Eitherize2[GRA](f)
|
||||
}
|
||||
|
||||
// Uneitherize2 converts a function with 2 parameters returning a [GRA] into a function with 2 parameters returning a tuple.
|
||||
// The first parameter is considered to be the [context.Context].
|
||||
func Uneitherize2[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1) (R, error), GIOA ~func() E.Either[error, R], T0, T1, R any](f func(T0, T1) GRA) F {
|
||||
return func(c context.Context, t0 T0, t1 T1) (R, error) {
|
||||
return E.UnwrapError(f(t0, t1)(c)())
|
||||
}
|
||||
}
|
||||
|
||||
// SequenceT2 converts 2 readers into a reader of a [T.Tuple2].
|
||||
func SequenceT2[
|
||||
GR_TUPLE2 ~func(context.Context) GIO_TUPLE2,
|
||||
@@ -364,6 +388,14 @@ func Eitherize3[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1
|
||||
return RE.Eitherize3[GRA](f)
|
||||
}
|
||||
|
||||
// Uneitherize3 converts a function with 3 parameters returning a [GRA] into a function with 3 parameters returning a tuple.
|
||||
// The first parameter is considered to be the [context.Context].
|
||||
func Uneitherize3[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1, T2) (R, error), GIOA ~func() E.Either[error, R], T0, T1, T2, R any](f func(T0, T1, T2) GRA) F {
|
||||
return func(c context.Context, t0 T0, t1 T1, t2 T2) (R, error) {
|
||||
return E.UnwrapError(f(t0, t1, t2)(c)())
|
||||
}
|
||||
}
|
||||
|
||||
// SequenceT3 converts 3 readers into a reader of a [T.Tuple3].
|
||||
func SequenceT3[
|
||||
GR_TUPLE3 ~func(context.Context) GIO_TUPLE3,
|
||||
@@ -610,6 +642,14 @@ func Eitherize4[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1
|
||||
return RE.Eitherize4[GRA](f)
|
||||
}
|
||||
|
||||
// Uneitherize4 converts a function with 4 parameters returning a [GRA] into a function with 4 parameters returning a tuple.
|
||||
// The first parameter is considered to be the [context.Context].
|
||||
func Uneitherize4[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1, T2, T3) (R, error), GIOA ~func() E.Either[error, R], T0, T1, T2, T3, R any](f func(T0, T1, T2, T3) GRA) F {
|
||||
return func(c context.Context, t0 T0, t1 T1, t2 T2, t3 T3) (R, error) {
|
||||
return E.UnwrapError(f(t0, t1, t2, t3)(c)())
|
||||
}
|
||||
}
|
||||
|
||||
// SequenceT4 converts 4 readers into a reader of a [T.Tuple4].
|
||||
func SequenceT4[
|
||||
GR_TUPLE4 ~func(context.Context) GIO_TUPLE4,
|
||||
@@ -907,6 +947,14 @@ func Eitherize5[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1
|
||||
return RE.Eitherize5[GRA](f)
|
||||
}
|
||||
|
||||
// Uneitherize5 converts a function with 5 parameters returning a [GRA] into a function with 5 parameters returning a tuple.
|
||||
// The first parameter is considered to be the [context.Context].
|
||||
func Uneitherize5[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1, T2, T3, T4) (R, error), GIOA ~func() E.Either[error, R], T0, T1, T2, T3, T4, R any](f func(T0, T1, T2, T3, T4) GRA) F {
|
||||
return func(c context.Context, t0 T0, t1 T1, t2 T2, t3 T3, t4 T4) (R, error) {
|
||||
return E.UnwrapError(f(t0, t1, t2, t3, t4)(c)())
|
||||
}
|
||||
}
|
||||
|
||||
// SequenceT5 converts 5 readers into a reader of a [T.Tuple5].
|
||||
func SequenceT5[
|
||||
GR_TUPLE5 ~func(context.Context) GIO_TUPLE5,
|
||||
@@ -1255,6 +1303,14 @@ func Eitherize6[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1
|
||||
return RE.Eitherize6[GRA](f)
|
||||
}
|
||||
|
||||
// Uneitherize6 converts a function with 6 parameters returning a [GRA] into a function with 6 parameters returning a tuple.
|
||||
// The first parameter is considered to be the [context.Context].
|
||||
func Uneitherize6[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1, T2, T3, T4, T5) (R, error), GIOA ~func() E.Either[error, R], T0, T1, T2, T3, T4, T5, R any](f func(T0, T1, T2, T3, T4, T5) GRA) F {
|
||||
return func(c context.Context, t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5) (R, error) {
|
||||
return E.UnwrapError(f(t0, t1, t2, t3, t4, t5)(c)())
|
||||
}
|
||||
}
|
||||
|
||||
// SequenceT6 converts 6 readers into a reader of a [T.Tuple6].
|
||||
func SequenceT6[
|
||||
GR_TUPLE6 ~func(context.Context) GIO_TUPLE6,
|
||||
@@ -1654,6 +1710,14 @@ func Eitherize7[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1
|
||||
return RE.Eitherize7[GRA](f)
|
||||
}
|
||||
|
||||
// Uneitherize7 converts a function with 7 parameters returning a [GRA] into a function with 7 parameters returning a tuple.
|
||||
// The first parameter is considered to be the [context.Context].
|
||||
func Uneitherize7[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6) (R, error), GIOA ~func() E.Either[error, R], T0, T1, T2, T3, T4, T5, T6, R any](f func(T0, T1, T2, T3, T4, T5, T6) GRA) F {
|
||||
return func(c context.Context, t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6) (R, error) {
|
||||
return E.UnwrapError(f(t0, t1, t2, t3, t4, t5, t6)(c)())
|
||||
}
|
||||
}
|
||||
|
||||
// SequenceT7 converts 7 readers into a reader of a [T.Tuple7].
|
||||
func SequenceT7[
|
||||
GR_TUPLE7 ~func(context.Context) GIO_TUPLE7,
|
||||
@@ -2104,6 +2168,14 @@ func Eitherize8[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1
|
||||
return RE.Eitherize8[GRA](f)
|
||||
}
|
||||
|
||||
// Uneitherize8 converts a function with 8 parameters returning a [GRA] into a function with 8 parameters returning a tuple.
|
||||
// The first parameter is considered to be the [context.Context].
|
||||
func Uneitherize8[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7) (R, error), GIOA ~func() E.Either[error, R], T0, T1, T2, T3, T4, T5, T6, T7, R any](f func(T0, T1, T2, T3, T4, T5, T6, T7) GRA) F {
|
||||
return func(c context.Context, t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7) (R, error) {
|
||||
return E.UnwrapError(f(t0, t1, t2, t3, t4, t5, t6, t7)(c)())
|
||||
}
|
||||
}
|
||||
|
||||
// SequenceT8 converts 8 readers into a reader of a [T.Tuple8].
|
||||
func SequenceT8[
|
||||
GR_TUPLE8 ~func(context.Context) GIO_TUPLE8,
|
||||
@@ -2605,6 +2677,14 @@ func Eitherize9[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1
|
||||
return RE.Eitherize9[GRA](f)
|
||||
}
|
||||
|
||||
// Uneitherize9 converts a function with 9 parameters returning a [GRA] into a function with 9 parameters returning a tuple.
|
||||
// The first parameter is considered to be the [context.Context].
|
||||
func Uneitherize9[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8) (R, error), GIOA ~func() E.Either[error, R], T0, T1, T2, T3, T4, T5, T6, T7, T8, R any](f func(T0, T1, T2, T3, T4, T5, T6, T7, T8) GRA) F {
|
||||
return func(c context.Context, t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8) (R, error) {
|
||||
return E.UnwrapError(f(t0, t1, t2, t3, t4, t5, t6, t7, t8)(c)())
|
||||
}
|
||||
}
|
||||
|
||||
// SequenceT9 converts 9 readers into a reader of a [T.Tuple9].
|
||||
func SequenceT9[
|
||||
GR_TUPLE9 ~func(context.Context) GIO_TUPLE9,
|
||||
@@ -3157,6 +3237,14 @@ func Eitherize10[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T
|
||||
return RE.Eitherize10[GRA](f)
|
||||
}
|
||||
|
||||
// Uneitherize10 converts a function with 10 parameters returning a [GRA] into a function with 10 parameters returning a tuple.
|
||||
// The first parameter is considered to be the [context.Context].
|
||||
func Uneitherize10[GRA ~func(context.Context) GIOA, F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (R, error), GIOA ~func() E.Either[error, R], T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, R any](f func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) GRA) F {
|
||||
return func(c context.Context, t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9) (R, error) {
|
||||
return E.UnwrapError(f(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9)(c)())
|
||||
}
|
||||
}
|
||||
|
||||
// SequenceT10 converts 10 readers into a reader of a [T.Tuple10].
|
||||
func SequenceT10[
|
||||
GR_TUPLE10 ~func(context.Context) GIO_TUPLE10,
|
||||
|
@@ -182,10 +182,7 @@ func withCancelCauseFunc[
|
||||
ma,
|
||||
IOE.Swap[GIOA, func() E.Either[A, error]],
|
||||
IOE.ChainFirstIOK[func() E.Either[A, error], func() any](func(err error) func() any {
|
||||
return IO.MakeIO[func() any](func() any {
|
||||
cancel(err)
|
||||
return nil
|
||||
})
|
||||
return IO.FromImpure[func() any](func() { cancel(err) })
|
||||
}),
|
||||
IOE.Swap[func() E.Either[A, error], GIOA],
|
||||
)
|
||||
|
72
context/readerioeither/http/builder/builder.go
Normal file
72
context/readerioeither/http/builder/builder.go
Normal file
@@ -0,0 +1,72 @@
|
||||
// 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 builder
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
RIOE "github.com/IBM/fp-go/context/readerioeither"
|
||||
RIOEH "github.com/IBM/fp-go/context/readerioeither/http"
|
||||
E "github.com/IBM/fp-go/either"
|
||||
F "github.com/IBM/fp-go/function"
|
||||
R "github.com/IBM/fp-go/http/builder"
|
||||
H "github.com/IBM/fp-go/http/headers"
|
||||
LZ "github.com/IBM/fp-go/lazy"
|
||||
O "github.com/IBM/fp-go/option"
|
||||
)
|
||||
|
||||
func Requester(builder *R.Builder) RIOEH.Requester {
|
||||
|
||||
withBody := F.Curry3(func(data []byte, url string, method string) RIOE.ReaderIOEither[*http.Request] {
|
||||
return RIOE.TryCatch(func(ctx context.Context) func() (*http.Request, error) {
|
||||
return func() (*http.Request, error) {
|
||||
req, err := http.NewRequestWithContext(ctx, method, url, bytes.NewReader(data))
|
||||
if err == nil {
|
||||
req.Header.Set(H.ContentLength, strconv.Itoa(len(data)))
|
||||
H.Monoid.Concat(req.Header, builder.GetHeaders())
|
||||
}
|
||||
return req, err
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
withoutBody := F.Curry2(func(url string, method string) RIOE.ReaderIOEither[*http.Request] {
|
||||
return RIOE.TryCatch(func(ctx context.Context) func() (*http.Request, error) {
|
||||
return func() (*http.Request, error) {
|
||||
req, err := http.NewRequestWithContext(ctx, method, url, nil)
|
||||
if err == nil {
|
||||
H.Monoid.Concat(req.Header, builder.GetHeaders())
|
||||
}
|
||||
return req, err
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
return F.Pipe5(
|
||||
builder.GetBody(),
|
||||
O.Fold(LZ.Of(E.Of[error](withoutBody)), E.Map[error](withBody)),
|
||||
E.Ap[func(string) RIOE.ReaderIOEither[*http.Request]](builder.GetTargetURL()),
|
||||
E.Flap[error, RIOE.ReaderIOEither[*http.Request]](builder.GetMethod()),
|
||||
E.GetOrElse(RIOE.Left[*http.Request]),
|
||||
RIOE.Map(func(req *http.Request) *http.Request {
|
||||
req.Header = H.Monoid.Concat(req.Header, builder.GetHeaders())
|
||||
return req
|
||||
}),
|
||||
)
|
||||
}
|
59
context/readerioeither/http/builder/builder_test.go
Normal file
59
context/readerioeither/http/builder/builder_test.go
Normal file
@@ -0,0 +1,59 @@
|
||||
// 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 builder
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
RIOE "github.com/IBM/fp-go/context/readerioeither"
|
||||
E "github.com/IBM/fp-go/either"
|
||||
F "github.com/IBM/fp-go/function"
|
||||
R "github.com/IBM/fp-go/http/builder"
|
||||
IO "github.com/IBM/fp-go/io"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestBuilderWithQuery(t *testing.T) {
|
||||
// add some query
|
||||
withLimit := R.WithQueryArg("limit")("10")
|
||||
withURL := R.WithURL("http://www.example.org?a=b")
|
||||
|
||||
b := F.Pipe2(
|
||||
R.Default,
|
||||
withLimit,
|
||||
withURL,
|
||||
)
|
||||
|
||||
req := F.Pipe3(
|
||||
b,
|
||||
Requester,
|
||||
RIOE.Map(func(r *http.Request) *url.URL {
|
||||
return r.URL
|
||||
}),
|
||||
RIOE.ChainFirstIOK(func(u *url.URL) IO.IO[any] {
|
||||
return IO.FromImpure(func() {
|
||||
q := u.Query()
|
||||
assert.Equal(t, "10", q.Get("limit"))
|
||||
assert.Equal(t, "b", q.Get("a"))
|
||||
})
|
||||
}),
|
||||
)
|
||||
|
||||
assert.True(t, E.IsRight(req(context.Background())()))
|
||||
}
|
@@ -26,7 +26,7 @@ import (
|
||||
IOE "github.com/IBM/fp-go/ioeither"
|
||||
IOEF "github.com/IBM/fp-go/ioeither/file"
|
||||
J "github.com/IBM/fp-go/json"
|
||||
T "github.com/IBM/fp-go/tuple"
|
||||
P "github.com/IBM/fp-go/pair"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -79,7 +79,7 @@ func ReadFullResponse(client Client) func(Requester) RIOE.ReaderIOEither[H.FullR
|
||||
IOE.Of[error, io.ReadCloser],
|
||||
IOEF.ReadAll[io.ReadCloser],
|
||||
),
|
||||
IOE.Map[error](F.Bind1st(T.MakeTuple2[*http.Response, []byte], resp)),
|
||||
IOE.Map[error](F.Bind1st(P.MakePair[*http.Response, []byte], resp)),
|
||||
)
|
||||
}),
|
||||
)
|
||||
@@ -103,16 +103,27 @@ func ReadText(client Client) func(Requester) RIOE.ReaderIOEither[string] {
|
||||
}
|
||||
|
||||
// ReadJson sends a request, reads the response and parses the response as JSON
|
||||
//
|
||||
// Deprecated: use [ReadJSON] instead
|
||||
func ReadJson[A any](client Client) func(Requester) RIOE.ReaderIOEither[A] {
|
||||
return ReadJSON[A](client)
|
||||
}
|
||||
|
||||
func readJSON(client Client) func(Requester) RIOE.ReaderIOEither[[]byte] {
|
||||
return F.Flow3(
|
||||
ReadFullResponse(client),
|
||||
RIOE.ChainFirstEitherK(F.Flow2(
|
||||
H.Response,
|
||||
H.ValidateJsonResponse,
|
||||
)),
|
||||
RIOE.ChainEitherK(F.Flow2(
|
||||
H.Body,
|
||||
J.Unmarshal[A],
|
||||
H.ValidateJSONResponse,
|
||||
)),
|
||||
RIOE.Map(H.Body),
|
||||
)
|
||||
}
|
||||
|
||||
// ReadJSON sends a request, reads the response and parses the response as JSON
|
||||
func ReadJSON[A any](client Client) func(Requester) RIOE.ReaderIOEither[A] {
|
||||
return F.Flow2(
|
||||
readJSON(client),
|
||||
RIOE.ChainEitherK(J.Unmarshal[A]),
|
||||
)
|
||||
}
|
||||
|
@@ -31,7 +31,7 @@ import (
|
||||
)
|
||||
|
||||
type PostItem struct {
|
||||
UserId uint `json:"userId"`
|
||||
UserID uint `json:"userId"`
|
||||
Id uint `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Body string `json:"body"`
|
||||
@@ -84,7 +84,7 @@ func TestSendSingleRequest(t *testing.T) {
|
||||
|
||||
req1 := MakeGetRequest("https://jsonplaceholder.typicode.com/posts/1")
|
||||
|
||||
readItem := ReadJson[PostItem](client)
|
||||
readItem := ReadJSON[PostItem](client)
|
||||
|
||||
resp1 := readItem(req1)
|
||||
|
||||
@@ -112,7 +112,7 @@ func TestSendSingleRequestWithHeaderUnsafe(t *testing.T) {
|
||||
R.Map(setHeaderUnsafe("Content-Type", "text/html")),
|
||||
)
|
||||
|
||||
readItem := ReadJson[PostItem](client)
|
||||
readItem := ReadJSON[PostItem](client)
|
||||
|
||||
resp1 := F.Pipe2(
|
||||
req1,
|
||||
@@ -140,7 +140,7 @@ func TestSendSingleRequestWithHeaderSafe(t *testing.T) {
|
||||
WithHeader("Content-Type", "text/html").
|
||||
Build()
|
||||
|
||||
readItem := ReadJson[PostItem](client)
|
||||
readItem := ReadJSON[PostItem](client)
|
||||
|
||||
response := F.Pipe2(
|
||||
request,
|
||||
|
@@ -25,6 +25,7 @@ import (
|
||||
IOE "github.com/IBM/fp-go/ioeither"
|
||||
L "github.com/IBM/fp-go/lazy"
|
||||
O "github.com/IBM/fp-go/option"
|
||||
RIO "github.com/IBM/fp-go/readerio"
|
||||
)
|
||||
|
||||
func FromEither[A any](e ET.Either[error, A]) ReaderIOEither[A] {
|
||||
@@ -192,8 +193,7 @@ func Memoize[A any](rdr ReaderIOEither[A]) ReaderIOEither[A] {
|
||||
}
|
||||
|
||||
// Flatten converts a nested [ReaderIOEither] into a [ReaderIOEither]
|
||||
func Flatten[
|
||||
A any](rdr ReaderIOEither[ReaderIOEither[A]]) ReaderIOEither[A] {
|
||||
func Flatten[A any](rdr ReaderIOEither[ReaderIOEither[A]]) ReaderIOEither[A] {
|
||||
return G.Flatten[ReaderIOEither[ReaderIOEither[A]]](rdr)
|
||||
}
|
||||
|
||||
@@ -204,3 +204,15 @@ func MonadFlap[B, A any](fab ReaderIOEither[func(A) B], a A) ReaderIOEither[B] {
|
||||
func Flap[B, A any](a A) func(ReaderIOEither[func(A) B]) ReaderIOEither[B] {
|
||||
return G.Flap[ReaderIOEither[func(A) B], ReaderIOEither[B]](a)
|
||||
}
|
||||
|
||||
func Fold[A, B any](onLeft func(error) ReaderIOEither[B], onRight func(A) ReaderIOEither[B]) func(ReaderIOEither[A]) ReaderIOEither[B] {
|
||||
return G.Fold[ReaderIOEither[B], ReaderIOEither[A]](onLeft, onRight)
|
||||
}
|
||||
|
||||
func GetOrElse[A any](onLeft func(error) RIO.ReaderIO[context.Context, A]) func(ReaderIOEither[A]) RIO.ReaderIO[context.Context, A] {
|
||||
return G.GetOrElse[RIO.ReaderIO[context.Context, A], ReaderIOEither[A]](onLeft)
|
||||
}
|
||||
|
||||
func OrLeft[A any](onLeft func(error) RIO.ReaderIO[context.Context, error]) func(ReaderIOEither[A]) ReaderIOEither[A] {
|
||||
return G.OrLeft[ReaderIOEither[A]](onLeft)
|
||||
}
|
||||
|
@@ -1,2 +1,3 @@
|
||||
@echo off
|
||||
go tool cover -html=build/cover.out -o build/cover.html
|
||||
go tool cover -html=build/cover.out -o build/cover.html
|
||||
cov-report -ex ".*/cli/.*.go|.*/gen.go|.*/binds.go" build\cover.out
|
||||
|
@@ -40,4 +40,4 @@
|
||||
// [MakeInjector]: [github.com/IBM/fp-go/di/erasure.MakeInjector]
|
||||
package di
|
||||
|
||||
//go:generate go run .. di --count 10 --filename gen.go
|
||||
//go:generate go run .. di --count 15 --filename gen.go
|
||||
|
@@ -127,7 +127,7 @@ func MakeInjector(providers []Provider) InjectableFactory {
|
||||
var resolved sync.Map
|
||||
|
||||
// provide a mapping for all providers
|
||||
factoryById := assembleProviders(providers)
|
||||
factoryByID := assembleProviders(providers)
|
||||
|
||||
// the actual factory, we need lazy initialization
|
||||
var injFct InjectableFactory
|
||||
@@ -149,7 +149,7 @@ func MakeInjector(providers []Provider) InjectableFactory {
|
||||
T.Map2(F.Flow3(
|
||||
Dependency.Id,
|
||||
R.Lookup[ProviderFactory, string],
|
||||
I.Ap[O.Option[ProviderFactory]](factoryById),
|
||||
I.Ap[O.Option[ProviderFactory]](factoryByID),
|
||||
), handleMissingProvider),
|
||||
T.Tupled2(O.MonadGetOrElse[ProviderFactory]),
|
||||
IG.Ap[ProviderFactory](injFct),
|
||||
|
897
di/gen.go
897
di/gen.go
@@ -1,6 +1,6 @@
|
||||
// Code generated by go generate; DO NOT EDIT.
|
||||
// This file was generated by robots at
|
||||
// 2023-12-18 21:40:11.0891062 +0100 CET m=+0.007755601
|
||||
// 2024-02-29 16:18:47.9991921 +0100 CET m=+0.012914901
|
||||
|
||||
package di
|
||||
|
||||
@@ -41,7 +41,7 @@ func MakeProviderFactory1[T1 any, R any](
|
||||
)
|
||||
}
|
||||
|
||||
// MakeTokenWithDefault1 creates an [InjectionToken] with a default implementation with 1 dependenciess
|
||||
// MakeTokenWithDefault1 creates an [InjectionToken] with a default implementation with 1 dependencies
|
||||
func MakeTokenWithDefault1[T1 any, R any](
|
||||
name string,
|
||||
d1 Dependency[T1],
|
||||
@@ -102,7 +102,7 @@ func MakeProviderFactory2[T1, T2 any, R any](
|
||||
)
|
||||
}
|
||||
|
||||
// MakeTokenWithDefault2 creates an [InjectionToken] with a default implementation with 2 dependenciess
|
||||
// MakeTokenWithDefault2 creates an [InjectionToken] with a default implementation with 2 dependencies
|
||||
func MakeTokenWithDefault2[T1, T2 any, R any](
|
||||
name string,
|
||||
d1 Dependency[T1],
|
||||
@@ -173,7 +173,7 @@ func MakeProviderFactory3[T1, T2, T3 any, R any](
|
||||
)
|
||||
}
|
||||
|
||||
// MakeTokenWithDefault3 creates an [InjectionToken] with a default implementation with 3 dependenciess
|
||||
// MakeTokenWithDefault3 creates an [InjectionToken] with a default implementation with 3 dependencies
|
||||
func MakeTokenWithDefault3[T1, T2, T3 any, R any](
|
||||
name string,
|
||||
d1 Dependency[T1],
|
||||
@@ -254,7 +254,7 @@ func MakeProviderFactory4[T1, T2, T3, T4 any, R any](
|
||||
)
|
||||
}
|
||||
|
||||
// MakeTokenWithDefault4 creates an [InjectionToken] with a default implementation with 4 dependenciess
|
||||
// MakeTokenWithDefault4 creates an [InjectionToken] with a default implementation with 4 dependencies
|
||||
func MakeTokenWithDefault4[T1, T2, T3, T4 any, R any](
|
||||
name string,
|
||||
d1 Dependency[T1],
|
||||
@@ -345,7 +345,7 @@ func MakeProviderFactory5[T1, T2, T3, T4, T5 any, R any](
|
||||
)
|
||||
}
|
||||
|
||||
// MakeTokenWithDefault5 creates an [InjectionToken] with a default implementation with 5 dependenciess
|
||||
// MakeTokenWithDefault5 creates an [InjectionToken] with a default implementation with 5 dependencies
|
||||
func MakeTokenWithDefault5[T1, T2, T3, T4, T5 any, R any](
|
||||
name string,
|
||||
d1 Dependency[T1],
|
||||
@@ -446,7 +446,7 @@ func MakeProviderFactory6[T1, T2, T3, T4, T5, T6 any, R any](
|
||||
)
|
||||
}
|
||||
|
||||
// MakeTokenWithDefault6 creates an [InjectionToken] with a default implementation with 6 dependenciess
|
||||
// MakeTokenWithDefault6 creates an [InjectionToken] with a default implementation with 6 dependencies
|
||||
func MakeTokenWithDefault6[T1, T2, T3, T4, T5, T6 any, R any](
|
||||
name string,
|
||||
d1 Dependency[T1],
|
||||
@@ -557,7 +557,7 @@ func MakeProviderFactory7[T1, T2, T3, T4, T5, T6, T7 any, R any](
|
||||
)
|
||||
}
|
||||
|
||||
// MakeTokenWithDefault7 creates an [InjectionToken] with a default implementation with 7 dependenciess
|
||||
// MakeTokenWithDefault7 creates an [InjectionToken] with a default implementation with 7 dependencies
|
||||
func MakeTokenWithDefault7[T1, T2, T3, T4, T5, T6, T7 any, R any](
|
||||
name string,
|
||||
d1 Dependency[T1],
|
||||
@@ -678,7 +678,7 @@ func MakeProviderFactory8[T1, T2, T3, T4, T5, T6, T7, T8 any, R any](
|
||||
)
|
||||
}
|
||||
|
||||
// MakeTokenWithDefault8 creates an [InjectionToken] with a default implementation with 8 dependenciess
|
||||
// MakeTokenWithDefault8 creates an [InjectionToken] with a default implementation with 8 dependencies
|
||||
func MakeTokenWithDefault8[T1, T2, T3, T4, T5, T6, T7, T8 any, R any](
|
||||
name string,
|
||||
d1 Dependency[T1],
|
||||
@@ -809,7 +809,7 @@ func MakeProviderFactory9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any, R any](
|
||||
)
|
||||
}
|
||||
|
||||
// MakeTokenWithDefault9 creates an [InjectionToken] with a default implementation with 9 dependenciess
|
||||
// MakeTokenWithDefault9 creates an [InjectionToken] with a default implementation with 9 dependencies
|
||||
func MakeTokenWithDefault9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any, R any](
|
||||
name string,
|
||||
d1 Dependency[T1],
|
||||
@@ -950,7 +950,7 @@ func MakeProviderFactory10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any, R any](
|
||||
)
|
||||
}
|
||||
|
||||
// MakeTokenWithDefault10 creates an [InjectionToken] with a default implementation with 10 dependenciess
|
||||
// MakeTokenWithDefault10 creates an [InjectionToken] with a default implementation with 10 dependencies
|
||||
func MakeTokenWithDefault10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any, R any](
|
||||
name string,
|
||||
d1 Dependency[T1],
|
||||
@@ -1011,3 +1011,878 @@ func MakeProvider10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any, R any](
|
||||
f,
|
||||
))
|
||||
}
|
||||
|
||||
// eraseProviderFactory11 creates a function that takes a variadic number of untyped arguments and from a function of 11 strongly typed arguments and 11 dependencies
|
||||
func eraseProviderFactory11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 any, R any](
|
||||
d1 Dependency[T1],
|
||||
d2 Dependency[T2],
|
||||
d3 Dependency[T3],
|
||||
d4 Dependency[T4],
|
||||
d5 Dependency[T5],
|
||||
d6 Dependency[T6],
|
||||
d7 Dependency[T7],
|
||||
d8 Dependency[T8],
|
||||
d9 Dependency[T9],
|
||||
d10 Dependency[T10],
|
||||
d11 Dependency[T11],
|
||||
f func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) IOE.IOEither[error, R]) func(params ...any) IOE.IOEither[error, any] {
|
||||
ft := eraseTuple(T.Tupled11(f))
|
||||
t1 := lookupAt[T1](0, d1)
|
||||
t2 := lookupAt[T2](1, d2)
|
||||
t3 := lookupAt[T3](2, d3)
|
||||
t4 := lookupAt[T4](3, d4)
|
||||
t5 := lookupAt[T5](4, d5)
|
||||
t6 := lookupAt[T6](5, d6)
|
||||
t7 := lookupAt[T7](6, d7)
|
||||
t8 := lookupAt[T8](7, d8)
|
||||
t9 := lookupAt[T9](8, d9)
|
||||
t10 := lookupAt[T10](9, d10)
|
||||
t11 := lookupAt[T11](10, d11)
|
||||
return func(params ...any) IOE.IOEither[error, any] {
|
||||
return ft(E.SequenceT11(
|
||||
t1(params),
|
||||
t2(params),
|
||||
t3(params),
|
||||
t4(params),
|
||||
t5(params),
|
||||
t6(params),
|
||||
t7(params),
|
||||
t8(params),
|
||||
t9(params),
|
||||
t10(params),
|
||||
t11(params),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
// MakeProviderFactory11 creates a [DIE.ProviderFactory] from a function with 11 arguments and 11 dependencies
|
||||
func MakeProviderFactory11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 any, R any](
|
||||
d1 Dependency[T1],
|
||||
d2 Dependency[T2],
|
||||
d3 Dependency[T3],
|
||||
d4 Dependency[T4],
|
||||
d5 Dependency[T5],
|
||||
d6 Dependency[T6],
|
||||
d7 Dependency[T7],
|
||||
d8 Dependency[T8],
|
||||
d9 Dependency[T9],
|
||||
d10 Dependency[T10],
|
||||
d11 Dependency[T11],
|
||||
f func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) IOE.IOEither[error, R],
|
||||
) DIE.ProviderFactory {
|
||||
return DIE.MakeProviderFactory(
|
||||
A.From[DIE.Dependency](
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
d4,
|
||||
d5,
|
||||
d6,
|
||||
d7,
|
||||
d8,
|
||||
d9,
|
||||
d10,
|
||||
d11,
|
||||
),
|
||||
eraseProviderFactory11(
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
d4,
|
||||
d5,
|
||||
d6,
|
||||
d7,
|
||||
d8,
|
||||
d9,
|
||||
d10,
|
||||
d11,
|
||||
f,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// MakeTokenWithDefault11 creates an [InjectionToken] with a default implementation with 11 dependencies
|
||||
func MakeTokenWithDefault11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 any, R any](
|
||||
name string,
|
||||
d1 Dependency[T1],
|
||||
d2 Dependency[T2],
|
||||
d3 Dependency[T3],
|
||||
d4 Dependency[T4],
|
||||
d5 Dependency[T5],
|
||||
d6 Dependency[T6],
|
||||
d7 Dependency[T7],
|
||||
d8 Dependency[T8],
|
||||
d9 Dependency[T9],
|
||||
d10 Dependency[T10],
|
||||
d11 Dependency[T11],
|
||||
f func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) IOE.IOEither[error, R],
|
||||
) InjectionToken[R] {
|
||||
return MakeTokenWithDefault[R](name, MakeProviderFactory11(
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
d4,
|
||||
d5,
|
||||
d6,
|
||||
d7,
|
||||
d8,
|
||||
d9,
|
||||
d10,
|
||||
d11,
|
||||
f,
|
||||
))
|
||||
}
|
||||
|
||||
// MakeProvider11 creates a [DIE.Provider] for an [InjectionToken] from a function with 11 dependencies
|
||||
func MakeProvider11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 any, R any](
|
||||
token InjectionToken[R],
|
||||
d1 Dependency[T1],
|
||||
d2 Dependency[T2],
|
||||
d3 Dependency[T3],
|
||||
d4 Dependency[T4],
|
||||
d5 Dependency[T5],
|
||||
d6 Dependency[T6],
|
||||
d7 Dependency[T7],
|
||||
d8 Dependency[T8],
|
||||
d9 Dependency[T9],
|
||||
d10 Dependency[T10],
|
||||
d11 Dependency[T11],
|
||||
f func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) IOE.IOEither[error, R],
|
||||
) DIE.Provider {
|
||||
return DIE.MakeProvider(
|
||||
token,
|
||||
MakeProviderFactory11(
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
d4,
|
||||
d5,
|
||||
d6,
|
||||
d7,
|
||||
d8,
|
||||
d9,
|
||||
d10,
|
||||
d11,
|
||||
f,
|
||||
))
|
||||
}
|
||||
|
||||
// eraseProviderFactory12 creates a function that takes a variadic number of untyped arguments and from a function of 12 strongly typed arguments and 12 dependencies
|
||||
func eraseProviderFactory12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 any, R any](
|
||||
d1 Dependency[T1],
|
||||
d2 Dependency[T2],
|
||||
d3 Dependency[T3],
|
||||
d4 Dependency[T4],
|
||||
d5 Dependency[T5],
|
||||
d6 Dependency[T6],
|
||||
d7 Dependency[T7],
|
||||
d8 Dependency[T8],
|
||||
d9 Dependency[T9],
|
||||
d10 Dependency[T10],
|
||||
d11 Dependency[T11],
|
||||
d12 Dependency[T12],
|
||||
f func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) IOE.IOEither[error, R]) func(params ...any) IOE.IOEither[error, any] {
|
||||
ft := eraseTuple(T.Tupled12(f))
|
||||
t1 := lookupAt[T1](0, d1)
|
||||
t2 := lookupAt[T2](1, d2)
|
||||
t3 := lookupAt[T3](2, d3)
|
||||
t4 := lookupAt[T4](3, d4)
|
||||
t5 := lookupAt[T5](4, d5)
|
||||
t6 := lookupAt[T6](5, d6)
|
||||
t7 := lookupAt[T7](6, d7)
|
||||
t8 := lookupAt[T8](7, d8)
|
||||
t9 := lookupAt[T9](8, d9)
|
||||
t10 := lookupAt[T10](9, d10)
|
||||
t11 := lookupAt[T11](10, d11)
|
||||
t12 := lookupAt[T12](11, d12)
|
||||
return func(params ...any) IOE.IOEither[error, any] {
|
||||
return ft(E.SequenceT12(
|
||||
t1(params),
|
||||
t2(params),
|
||||
t3(params),
|
||||
t4(params),
|
||||
t5(params),
|
||||
t6(params),
|
||||
t7(params),
|
||||
t8(params),
|
||||
t9(params),
|
||||
t10(params),
|
||||
t11(params),
|
||||
t12(params),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
// MakeProviderFactory12 creates a [DIE.ProviderFactory] from a function with 12 arguments and 12 dependencies
|
||||
func MakeProviderFactory12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 any, R any](
|
||||
d1 Dependency[T1],
|
||||
d2 Dependency[T2],
|
||||
d3 Dependency[T3],
|
||||
d4 Dependency[T4],
|
||||
d5 Dependency[T5],
|
||||
d6 Dependency[T6],
|
||||
d7 Dependency[T7],
|
||||
d8 Dependency[T8],
|
||||
d9 Dependency[T9],
|
||||
d10 Dependency[T10],
|
||||
d11 Dependency[T11],
|
||||
d12 Dependency[T12],
|
||||
f func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) IOE.IOEither[error, R],
|
||||
) DIE.ProviderFactory {
|
||||
return DIE.MakeProviderFactory(
|
||||
A.From[DIE.Dependency](
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
d4,
|
||||
d5,
|
||||
d6,
|
||||
d7,
|
||||
d8,
|
||||
d9,
|
||||
d10,
|
||||
d11,
|
||||
d12,
|
||||
),
|
||||
eraseProviderFactory12(
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
d4,
|
||||
d5,
|
||||
d6,
|
||||
d7,
|
||||
d8,
|
||||
d9,
|
||||
d10,
|
||||
d11,
|
||||
d12,
|
||||
f,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// MakeTokenWithDefault12 creates an [InjectionToken] with a default implementation with 12 dependencies
|
||||
func MakeTokenWithDefault12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 any, R any](
|
||||
name string,
|
||||
d1 Dependency[T1],
|
||||
d2 Dependency[T2],
|
||||
d3 Dependency[T3],
|
||||
d4 Dependency[T4],
|
||||
d5 Dependency[T5],
|
||||
d6 Dependency[T6],
|
||||
d7 Dependency[T7],
|
||||
d8 Dependency[T8],
|
||||
d9 Dependency[T9],
|
||||
d10 Dependency[T10],
|
||||
d11 Dependency[T11],
|
||||
d12 Dependency[T12],
|
||||
f func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) IOE.IOEither[error, R],
|
||||
) InjectionToken[R] {
|
||||
return MakeTokenWithDefault[R](name, MakeProviderFactory12(
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
d4,
|
||||
d5,
|
||||
d6,
|
||||
d7,
|
||||
d8,
|
||||
d9,
|
||||
d10,
|
||||
d11,
|
||||
d12,
|
||||
f,
|
||||
))
|
||||
}
|
||||
|
||||
// MakeProvider12 creates a [DIE.Provider] for an [InjectionToken] from a function with 12 dependencies
|
||||
func MakeProvider12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 any, R any](
|
||||
token InjectionToken[R],
|
||||
d1 Dependency[T1],
|
||||
d2 Dependency[T2],
|
||||
d3 Dependency[T3],
|
||||
d4 Dependency[T4],
|
||||
d5 Dependency[T5],
|
||||
d6 Dependency[T6],
|
||||
d7 Dependency[T7],
|
||||
d8 Dependency[T8],
|
||||
d9 Dependency[T9],
|
||||
d10 Dependency[T10],
|
||||
d11 Dependency[T11],
|
||||
d12 Dependency[T12],
|
||||
f func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) IOE.IOEither[error, R],
|
||||
) DIE.Provider {
|
||||
return DIE.MakeProvider(
|
||||
token,
|
||||
MakeProviderFactory12(
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
d4,
|
||||
d5,
|
||||
d6,
|
||||
d7,
|
||||
d8,
|
||||
d9,
|
||||
d10,
|
||||
d11,
|
||||
d12,
|
||||
f,
|
||||
))
|
||||
}
|
||||
|
||||
// eraseProviderFactory13 creates a function that takes a variadic number of untyped arguments and from a function of 13 strongly typed arguments and 13 dependencies
|
||||
func eraseProviderFactory13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 any, R any](
|
||||
d1 Dependency[T1],
|
||||
d2 Dependency[T2],
|
||||
d3 Dependency[T3],
|
||||
d4 Dependency[T4],
|
||||
d5 Dependency[T5],
|
||||
d6 Dependency[T6],
|
||||
d7 Dependency[T7],
|
||||
d8 Dependency[T8],
|
||||
d9 Dependency[T9],
|
||||
d10 Dependency[T10],
|
||||
d11 Dependency[T11],
|
||||
d12 Dependency[T12],
|
||||
d13 Dependency[T13],
|
||||
f func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) IOE.IOEither[error, R]) func(params ...any) IOE.IOEither[error, any] {
|
||||
ft := eraseTuple(T.Tupled13(f))
|
||||
t1 := lookupAt[T1](0, d1)
|
||||
t2 := lookupAt[T2](1, d2)
|
||||
t3 := lookupAt[T3](2, d3)
|
||||
t4 := lookupAt[T4](3, d4)
|
||||
t5 := lookupAt[T5](4, d5)
|
||||
t6 := lookupAt[T6](5, d6)
|
||||
t7 := lookupAt[T7](6, d7)
|
||||
t8 := lookupAt[T8](7, d8)
|
||||
t9 := lookupAt[T9](8, d9)
|
||||
t10 := lookupAt[T10](9, d10)
|
||||
t11 := lookupAt[T11](10, d11)
|
||||
t12 := lookupAt[T12](11, d12)
|
||||
t13 := lookupAt[T13](12, d13)
|
||||
return func(params ...any) IOE.IOEither[error, any] {
|
||||
return ft(E.SequenceT13(
|
||||
t1(params),
|
||||
t2(params),
|
||||
t3(params),
|
||||
t4(params),
|
||||
t5(params),
|
||||
t6(params),
|
||||
t7(params),
|
||||
t8(params),
|
||||
t9(params),
|
||||
t10(params),
|
||||
t11(params),
|
||||
t12(params),
|
||||
t13(params),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
// MakeProviderFactory13 creates a [DIE.ProviderFactory] from a function with 13 arguments and 13 dependencies
|
||||
func MakeProviderFactory13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 any, R any](
|
||||
d1 Dependency[T1],
|
||||
d2 Dependency[T2],
|
||||
d3 Dependency[T3],
|
||||
d4 Dependency[T4],
|
||||
d5 Dependency[T5],
|
||||
d6 Dependency[T6],
|
||||
d7 Dependency[T7],
|
||||
d8 Dependency[T8],
|
||||
d9 Dependency[T9],
|
||||
d10 Dependency[T10],
|
||||
d11 Dependency[T11],
|
||||
d12 Dependency[T12],
|
||||
d13 Dependency[T13],
|
||||
f func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) IOE.IOEither[error, R],
|
||||
) DIE.ProviderFactory {
|
||||
return DIE.MakeProviderFactory(
|
||||
A.From[DIE.Dependency](
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
d4,
|
||||
d5,
|
||||
d6,
|
||||
d7,
|
||||
d8,
|
||||
d9,
|
||||
d10,
|
||||
d11,
|
||||
d12,
|
||||
d13,
|
||||
),
|
||||
eraseProviderFactory13(
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
d4,
|
||||
d5,
|
||||
d6,
|
||||
d7,
|
||||
d8,
|
||||
d9,
|
||||
d10,
|
||||
d11,
|
||||
d12,
|
||||
d13,
|
||||
f,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// MakeTokenWithDefault13 creates an [InjectionToken] with a default implementation with 13 dependencies
|
||||
func MakeTokenWithDefault13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 any, R any](
|
||||
name string,
|
||||
d1 Dependency[T1],
|
||||
d2 Dependency[T2],
|
||||
d3 Dependency[T3],
|
||||
d4 Dependency[T4],
|
||||
d5 Dependency[T5],
|
||||
d6 Dependency[T6],
|
||||
d7 Dependency[T7],
|
||||
d8 Dependency[T8],
|
||||
d9 Dependency[T9],
|
||||
d10 Dependency[T10],
|
||||
d11 Dependency[T11],
|
||||
d12 Dependency[T12],
|
||||
d13 Dependency[T13],
|
||||
f func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) IOE.IOEither[error, R],
|
||||
) InjectionToken[R] {
|
||||
return MakeTokenWithDefault[R](name, MakeProviderFactory13(
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
d4,
|
||||
d5,
|
||||
d6,
|
||||
d7,
|
||||
d8,
|
||||
d9,
|
||||
d10,
|
||||
d11,
|
||||
d12,
|
||||
d13,
|
||||
f,
|
||||
))
|
||||
}
|
||||
|
||||
// MakeProvider13 creates a [DIE.Provider] for an [InjectionToken] from a function with 13 dependencies
|
||||
func MakeProvider13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 any, R any](
|
||||
token InjectionToken[R],
|
||||
d1 Dependency[T1],
|
||||
d2 Dependency[T2],
|
||||
d3 Dependency[T3],
|
||||
d4 Dependency[T4],
|
||||
d5 Dependency[T5],
|
||||
d6 Dependency[T6],
|
||||
d7 Dependency[T7],
|
||||
d8 Dependency[T8],
|
||||
d9 Dependency[T9],
|
||||
d10 Dependency[T10],
|
||||
d11 Dependency[T11],
|
||||
d12 Dependency[T12],
|
||||
d13 Dependency[T13],
|
||||
f func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) IOE.IOEither[error, R],
|
||||
) DIE.Provider {
|
||||
return DIE.MakeProvider(
|
||||
token,
|
||||
MakeProviderFactory13(
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
d4,
|
||||
d5,
|
||||
d6,
|
||||
d7,
|
||||
d8,
|
||||
d9,
|
||||
d10,
|
||||
d11,
|
||||
d12,
|
||||
d13,
|
||||
f,
|
||||
))
|
||||
}
|
||||
|
||||
// eraseProviderFactory14 creates a function that takes a variadic number of untyped arguments and from a function of 14 strongly typed arguments and 14 dependencies
|
||||
func eraseProviderFactory14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 any, R any](
|
||||
d1 Dependency[T1],
|
||||
d2 Dependency[T2],
|
||||
d3 Dependency[T3],
|
||||
d4 Dependency[T4],
|
||||
d5 Dependency[T5],
|
||||
d6 Dependency[T6],
|
||||
d7 Dependency[T7],
|
||||
d8 Dependency[T8],
|
||||
d9 Dependency[T9],
|
||||
d10 Dependency[T10],
|
||||
d11 Dependency[T11],
|
||||
d12 Dependency[T12],
|
||||
d13 Dependency[T13],
|
||||
d14 Dependency[T14],
|
||||
f func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) IOE.IOEither[error, R]) func(params ...any) IOE.IOEither[error, any] {
|
||||
ft := eraseTuple(T.Tupled14(f))
|
||||
t1 := lookupAt[T1](0, d1)
|
||||
t2 := lookupAt[T2](1, d2)
|
||||
t3 := lookupAt[T3](2, d3)
|
||||
t4 := lookupAt[T4](3, d4)
|
||||
t5 := lookupAt[T5](4, d5)
|
||||
t6 := lookupAt[T6](5, d6)
|
||||
t7 := lookupAt[T7](6, d7)
|
||||
t8 := lookupAt[T8](7, d8)
|
||||
t9 := lookupAt[T9](8, d9)
|
||||
t10 := lookupAt[T10](9, d10)
|
||||
t11 := lookupAt[T11](10, d11)
|
||||
t12 := lookupAt[T12](11, d12)
|
||||
t13 := lookupAt[T13](12, d13)
|
||||
t14 := lookupAt[T14](13, d14)
|
||||
return func(params ...any) IOE.IOEither[error, any] {
|
||||
return ft(E.SequenceT14(
|
||||
t1(params),
|
||||
t2(params),
|
||||
t3(params),
|
||||
t4(params),
|
||||
t5(params),
|
||||
t6(params),
|
||||
t7(params),
|
||||
t8(params),
|
||||
t9(params),
|
||||
t10(params),
|
||||
t11(params),
|
||||
t12(params),
|
||||
t13(params),
|
||||
t14(params),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
// MakeProviderFactory14 creates a [DIE.ProviderFactory] from a function with 14 arguments and 14 dependencies
|
||||
func MakeProviderFactory14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 any, R any](
|
||||
d1 Dependency[T1],
|
||||
d2 Dependency[T2],
|
||||
d3 Dependency[T3],
|
||||
d4 Dependency[T4],
|
||||
d5 Dependency[T5],
|
||||
d6 Dependency[T6],
|
||||
d7 Dependency[T7],
|
||||
d8 Dependency[T8],
|
||||
d9 Dependency[T9],
|
||||
d10 Dependency[T10],
|
||||
d11 Dependency[T11],
|
||||
d12 Dependency[T12],
|
||||
d13 Dependency[T13],
|
||||
d14 Dependency[T14],
|
||||
f func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) IOE.IOEither[error, R],
|
||||
) DIE.ProviderFactory {
|
||||
return DIE.MakeProviderFactory(
|
||||
A.From[DIE.Dependency](
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
d4,
|
||||
d5,
|
||||
d6,
|
||||
d7,
|
||||
d8,
|
||||
d9,
|
||||
d10,
|
||||
d11,
|
||||
d12,
|
||||
d13,
|
||||
d14,
|
||||
),
|
||||
eraseProviderFactory14(
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
d4,
|
||||
d5,
|
||||
d6,
|
||||
d7,
|
||||
d8,
|
||||
d9,
|
||||
d10,
|
||||
d11,
|
||||
d12,
|
||||
d13,
|
||||
d14,
|
||||
f,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// MakeTokenWithDefault14 creates an [InjectionToken] with a default implementation with 14 dependencies
|
||||
func MakeTokenWithDefault14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 any, R any](
|
||||
name string,
|
||||
d1 Dependency[T1],
|
||||
d2 Dependency[T2],
|
||||
d3 Dependency[T3],
|
||||
d4 Dependency[T4],
|
||||
d5 Dependency[T5],
|
||||
d6 Dependency[T6],
|
||||
d7 Dependency[T7],
|
||||
d8 Dependency[T8],
|
||||
d9 Dependency[T9],
|
||||
d10 Dependency[T10],
|
||||
d11 Dependency[T11],
|
||||
d12 Dependency[T12],
|
||||
d13 Dependency[T13],
|
||||
d14 Dependency[T14],
|
||||
f func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) IOE.IOEither[error, R],
|
||||
) InjectionToken[R] {
|
||||
return MakeTokenWithDefault[R](name, MakeProviderFactory14(
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
d4,
|
||||
d5,
|
||||
d6,
|
||||
d7,
|
||||
d8,
|
||||
d9,
|
||||
d10,
|
||||
d11,
|
||||
d12,
|
||||
d13,
|
||||
d14,
|
||||
f,
|
||||
))
|
||||
}
|
||||
|
||||
// MakeProvider14 creates a [DIE.Provider] for an [InjectionToken] from a function with 14 dependencies
|
||||
func MakeProvider14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 any, R any](
|
||||
token InjectionToken[R],
|
||||
d1 Dependency[T1],
|
||||
d2 Dependency[T2],
|
||||
d3 Dependency[T3],
|
||||
d4 Dependency[T4],
|
||||
d5 Dependency[T5],
|
||||
d6 Dependency[T6],
|
||||
d7 Dependency[T7],
|
||||
d8 Dependency[T8],
|
||||
d9 Dependency[T9],
|
||||
d10 Dependency[T10],
|
||||
d11 Dependency[T11],
|
||||
d12 Dependency[T12],
|
||||
d13 Dependency[T13],
|
||||
d14 Dependency[T14],
|
||||
f func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) IOE.IOEither[error, R],
|
||||
) DIE.Provider {
|
||||
return DIE.MakeProvider(
|
||||
token,
|
||||
MakeProviderFactory14(
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
d4,
|
||||
d5,
|
||||
d6,
|
||||
d7,
|
||||
d8,
|
||||
d9,
|
||||
d10,
|
||||
d11,
|
||||
d12,
|
||||
d13,
|
||||
d14,
|
||||
f,
|
||||
))
|
||||
}
|
||||
|
||||
// eraseProviderFactory15 creates a function that takes a variadic number of untyped arguments and from a function of 15 strongly typed arguments and 15 dependencies
|
||||
func eraseProviderFactory15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 any, R any](
|
||||
d1 Dependency[T1],
|
||||
d2 Dependency[T2],
|
||||
d3 Dependency[T3],
|
||||
d4 Dependency[T4],
|
||||
d5 Dependency[T5],
|
||||
d6 Dependency[T6],
|
||||
d7 Dependency[T7],
|
||||
d8 Dependency[T8],
|
||||
d9 Dependency[T9],
|
||||
d10 Dependency[T10],
|
||||
d11 Dependency[T11],
|
||||
d12 Dependency[T12],
|
||||
d13 Dependency[T13],
|
||||
d14 Dependency[T14],
|
||||
d15 Dependency[T15],
|
||||
f func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) IOE.IOEither[error, R]) func(params ...any) IOE.IOEither[error, any] {
|
||||
ft := eraseTuple(T.Tupled15(f))
|
||||
t1 := lookupAt[T1](0, d1)
|
||||
t2 := lookupAt[T2](1, d2)
|
||||
t3 := lookupAt[T3](2, d3)
|
||||
t4 := lookupAt[T4](3, d4)
|
||||
t5 := lookupAt[T5](4, d5)
|
||||
t6 := lookupAt[T6](5, d6)
|
||||
t7 := lookupAt[T7](6, d7)
|
||||
t8 := lookupAt[T8](7, d8)
|
||||
t9 := lookupAt[T9](8, d9)
|
||||
t10 := lookupAt[T10](9, d10)
|
||||
t11 := lookupAt[T11](10, d11)
|
||||
t12 := lookupAt[T12](11, d12)
|
||||
t13 := lookupAt[T13](12, d13)
|
||||
t14 := lookupAt[T14](13, d14)
|
||||
t15 := lookupAt[T15](14, d15)
|
||||
return func(params ...any) IOE.IOEither[error, any] {
|
||||
return ft(E.SequenceT15(
|
||||
t1(params),
|
||||
t2(params),
|
||||
t3(params),
|
||||
t4(params),
|
||||
t5(params),
|
||||
t6(params),
|
||||
t7(params),
|
||||
t8(params),
|
||||
t9(params),
|
||||
t10(params),
|
||||
t11(params),
|
||||
t12(params),
|
||||
t13(params),
|
||||
t14(params),
|
||||
t15(params),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
// MakeProviderFactory15 creates a [DIE.ProviderFactory] from a function with 15 arguments and 15 dependencies
|
||||
func MakeProviderFactory15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 any, R any](
|
||||
d1 Dependency[T1],
|
||||
d2 Dependency[T2],
|
||||
d3 Dependency[T3],
|
||||
d4 Dependency[T4],
|
||||
d5 Dependency[T5],
|
||||
d6 Dependency[T6],
|
||||
d7 Dependency[T7],
|
||||
d8 Dependency[T8],
|
||||
d9 Dependency[T9],
|
||||
d10 Dependency[T10],
|
||||
d11 Dependency[T11],
|
||||
d12 Dependency[T12],
|
||||
d13 Dependency[T13],
|
||||
d14 Dependency[T14],
|
||||
d15 Dependency[T15],
|
||||
f func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) IOE.IOEither[error, R],
|
||||
) DIE.ProviderFactory {
|
||||
return DIE.MakeProviderFactory(
|
||||
A.From[DIE.Dependency](
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
d4,
|
||||
d5,
|
||||
d6,
|
||||
d7,
|
||||
d8,
|
||||
d9,
|
||||
d10,
|
||||
d11,
|
||||
d12,
|
||||
d13,
|
||||
d14,
|
||||
d15,
|
||||
),
|
||||
eraseProviderFactory15(
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
d4,
|
||||
d5,
|
||||
d6,
|
||||
d7,
|
||||
d8,
|
||||
d9,
|
||||
d10,
|
||||
d11,
|
||||
d12,
|
||||
d13,
|
||||
d14,
|
||||
d15,
|
||||
f,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// MakeTokenWithDefault15 creates an [InjectionToken] with a default implementation with 15 dependencies
|
||||
func MakeTokenWithDefault15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 any, R any](
|
||||
name string,
|
||||
d1 Dependency[T1],
|
||||
d2 Dependency[T2],
|
||||
d3 Dependency[T3],
|
||||
d4 Dependency[T4],
|
||||
d5 Dependency[T5],
|
||||
d6 Dependency[T6],
|
||||
d7 Dependency[T7],
|
||||
d8 Dependency[T8],
|
||||
d9 Dependency[T9],
|
||||
d10 Dependency[T10],
|
||||
d11 Dependency[T11],
|
||||
d12 Dependency[T12],
|
||||
d13 Dependency[T13],
|
||||
d14 Dependency[T14],
|
||||
d15 Dependency[T15],
|
||||
f func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) IOE.IOEither[error, R],
|
||||
) InjectionToken[R] {
|
||||
return MakeTokenWithDefault[R](name, MakeProviderFactory15(
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
d4,
|
||||
d5,
|
||||
d6,
|
||||
d7,
|
||||
d8,
|
||||
d9,
|
||||
d10,
|
||||
d11,
|
||||
d12,
|
||||
d13,
|
||||
d14,
|
||||
d15,
|
||||
f,
|
||||
))
|
||||
}
|
||||
|
||||
// MakeProvider15 creates a [DIE.Provider] for an [InjectionToken] from a function with 15 dependencies
|
||||
func MakeProvider15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 any, R any](
|
||||
token InjectionToken[R],
|
||||
d1 Dependency[T1],
|
||||
d2 Dependency[T2],
|
||||
d3 Dependency[T3],
|
||||
d4 Dependency[T4],
|
||||
d5 Dependency[T5],
|
||||
d6 Dependency[T6],
|
||||
d7 Dependency[T7],
|
||||
d8 Dependency[T8],
|
||||
d9 Dependency[T9],
|
||||
d10 Dependency[T10],
|
||||
d11 Dependency[T11],
|
||||
d12 Dependency[T12],
|
||||
d13 Dependency[T13],
|
||||
d14 Dependency[T14],
|
||||
d15 Dependency[T15],
|
||||
f func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) IOE.IOEither[error, R],
|
||||
) DIE.Provider {
|
||||
return DIE.MakeProvider(
|
||||
token,
|
||||
MakeProviderFactory15(
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
d4,
|
||||
d5,
|
||||
d6,
|
||||
d7,
|
||||
d8,
|
||||
d9,
|
||||
d10,
|
||||
d11,
|
||||
d12,
|
||||
d13,
|
||||
d14,
|
||||
d15,
|
||||
f,
|
||||
))
|
||||
}
|
||||
|
@@ -41,7 +41,7 @@ func eraseTuple[A, R any](f func(A) IOE.IOEither[error, R]) func(E.Either[error,
|
||||
}
|
||||
|
||||
func eraseProviderFactory0[R any](f IOE.IOEither[error, R]) func(params ...any) IOE.IOEither[error, any] {
|
||||
return func(params ...any) IOE.IOEither[error, any] {
|
||||
return func(_ ...any) IOE.IOEither[error, any] {
|
||||
return F.Pipe1(
|
||||
f,
|
||||
IOE.Map[error](F.ToAny[R]),
|
||||
|
39
di/token.go
39
di/token.go
@@ -65,34 +65,38 @@ type MultiInjectionToken[T any] interface {
|
||||
}
|
||||
|
||||
// makeID creates a generator of unique string IDs
|
||||
func makeId() IO.IO[string] {
|
||||
func makeID() IO.IO[string] {
|
||||
var count atomic.Int64
|
||||
return IO.MakeIO(func() string {
|
||||
return strconv.FormatInt(count.Add(1), 16)
|
||||
})
|
||||
}
|
||||
|
||||
// genId is the common generator of unique string IDs
|
||||
var genId = makeId()
|
||||
// genID is the common generator of unique string IDs
|
||||
var genID = makeID()
|
||||
|
||||
type token[T any] struct {
|
||||
type tokenBase struct {
|
||||
name string
|
||||
id string
|
||||
flag int
|
||||
toType func(val any) E.Either[error, T]
|
||||
providerFactory O.Option[DIE.ProviderFactory]
|
||||
}
|
||||
|
||||
type token[T any] struct {
|
||||
base *tokenBase
|
||||
toType func(val any) E.Either[error, T]
|
||||
}
|
||||
|
||||
func (t *token[T]) Id() string {
|
||||
return t.id
|
||||
return t.base.id
|
||||
}
|
||||
|
||||
func (t *token[T]) Flag() int {
|
||||
return t.flag
|
||||
return t.base.flag
|
||||
}
|
||||
|
||||
func (t *token[T]) String() string {
|
||||
return t.name
|
||||
return t.base.name
|
||||
}
|
||||
|
||||
func (t *token[T]) Unerase(val any) E.Either[error, T] {
|
||||
@@ -100,11 +104,14 @@ func (t *token[T]) Unerase(val any) E.Either[error, T] {
|
||||
}
|
||||
|
||||
func (t *token[T]) ProviderFactory() O.Option[DIE.ProviderFactory] {
|
||||
return t.providerFactory
|
||||
return t.base.providerFactory
|
||||
}
|
||||
func makeTokenBase(name string, id string, typ int, providerFactory O.Option[DIE.ProviderFactory]) *tokenBase {
|
||||
return &tokenBase{name, id, typ, providerFactory}
|
||||
}
|
||||
|
||||
func makeToken[T any](name string, id string, typ int, unerase func(val any) E.Either[error, T], providerFactory O.Option[DIE.ProviderFactory]) Dependency[T] {
|
||||
return &token[T]{name, id, typ, unerase, providerFactory}
|
||||
return &token[T]{makeTokenBase(name, id, typ, providerFactory), unerase}
|
||||
}
|
||||
|
||||
type injectionToken[T any] struct {
|
||||
@@ -136,7 +143,7 @@ func (i *injectionToken[T]) IOOption() Dependency[IOO.IOOption[T]] {
|
||||
}
|
||||
|
||||
func (i *injectionToken[T]) ProviderFactory() O.Option[DIE.ProviderFactory] {
|
||||
return i.providerFactory
|
||||
return i.base.providerFactory
|
||||
}
|
||||
|
||||
func (m *multiInjectionToken[T]) Container() InjectionToken[[]T] {
|
||||
@@ -149,10 +156,10 @@ func (m *multiInjectionToken[T]) Item() InjectionToken[T] {
|
||||
|
||||
// makeToken create a unique [InjectionToken] for a specific type
|
||||
func makeInjectionToken[T any](name string, providerFactory O.Option[DIE.ProviderFactory]) InjectionToken[T] {
|
||||
id := genId()
|
||||
id := genID()
|
||||
toIdentity := toType[T]()
|
||||
return &injectionToken[T]{
|
||||
token[T]{name, id, DIE.Identity, toIdentity, providerFactory},
|
||||
token[T]{makeTokenBase(name, id, DIE.Identity, providerFactory), toIdentity},
|
||||
makeToken[O.Option[T]](fmt.Sprintf("Option[%s]", name), id, DIE.Option, toOptionType(toIdentity), providerFactory),
|
||||
makeToken[IOE.IOEither[error, T]](fmt.Sprintf("IOEither[%s]", name), id, DIE.IOEither, toIOEitherType(toIdentity), providerFactory),
|
||||
makeToken[IOO.IOOption[T]](fmt.Sprintf("IOOption[%s]", name), id, DIE.IOOption, toIOOptionType(toIdentity), providerFactory),
|
||||
@@ -171,7 +178,7 @@ func MakeTokenWithDefault[T any](name string, providerFactory DIE.ProviderFactor
|
||||
|
||||
// MakeMultiToken creates a [MultiInjectionToken]
|
||||
func MakeMultiToken[T any](name string) MultiInjectionToken[T] {
|
||||
id := genId()
|
||||
id := genID()
|
||||
toItem := toType[T]()
|
||||
toContainer := toArrayType(toItem)
|
||||
containerName := fmt.Sprintf("Container[%s]", name)
|
||||
@@ -180,14 +187,14 @@ func MakeMultiToken[T any](name string) MultiInjectionToken[T] {
|
||||
providerFactory := O.None[DIE.ProviderFactory]()
|
||||
// container
|
||||
container := &injectionToken[[]T]{
|
||||
token[[]T]{containerName, id, DIE.Multi | DIE.Identity, toContainer, providerFactory},
|
||||
token[[]T]{makeTokenBase(containerName, id, DIE.Multi|DIE.Identity, providerFactory), toContainer},
|
||||
makeToken[O.Option[[]T]](fmt.Sprintf("Option[%s]", containerName), id, DIE.Multi|DIE.Option, toOptionType(toContainer), providerFactory),
|
||||
makeToken[IOE.IOEither[error, []T]](fmt.Sprintf("IOEither[%s]", containerName), id, DIE.Multi|DIE.IOEither, toIOEitherType(toContainer), providerFactory),
|
||||
makeToken[IOO.IOOption[[]T]](fmt.Sprintf("IOOption[%s]", containerName), id, DIE.Multi|DIE.IOOption, toIOOptionType(toContainer), providerFactory),
|
||||
}
|
||||
// item
|
||||
item := &injectionToken[T]{
|
||||
token[T]{itemName, id, DIE.Item | DIE.Identity, toItem, providerFactory},
|
||||
token[T]{makeTokenBase(itemName, id, DIE.Item|DIE.Identity, providerFactory), toItem},
|
||||
makeToken[O.Option[T]](fmt.Sprintf("Option[%s]", itemName), id, DIE.Item|DIE.Option, toOptionType(toItem), providerFactory),
|
||||
makeToken[IOE.IOEither[error, T]](fmt.Sprintf("IOEither[%s]", itemName), id, DIE.Item|DIE.IOEither, toIOEitherType(toItem), providerFactory),
|
||||
makeToken[IOO.IOOption[T]](fmt.Sprintf("IOOption[%s]", itemName), id, DIE.Item|DIE.IOOption, toIOOptionType(toItem), providerFactory),
|
||||
|
15
di/utils.go
15
di/utils.go
@@ -25,6 +25,13 @@ import (
|
||||
O "github.com/IBM/fp-go/option"
|
||||
)
|
||||
|
||||
var (
|
||||
toOptionAny = toType[O.Option[any]]()
|
||||
toIOEitherAny = toType[IOE.IOEither[error, any]]()
|
||||
toIOOptionAny = toType[IOO.IOOption[any]]()
|
||||
toArrayAny = toType[[]any]()
|
||||
)
|
||||
|
||||
// asDependency converts a generic type to a [DIE.Dependency]
|
||||
func asDependency[T DIE.Dependency](t T) DIE.Dependency {
|
||||
return t
|
||||
@@ -38,7 +45,7 @@ func toType[T any]() func(t any) E.Either[error, T] {
|
||||
// toOptionType converts an any to an Option[any] and then to an Option[T]
|
||||
func toOptionType[T any](item func(any) E.Either[error, T]) func(t any) E.Either[error, O.Option[T]] {
|
||||
return F.Flow2(
|
||||
toType[O.Option[any]](),
|
||||
toOptionAny,
|
||||
E.Chain(O.Fold(
|
||||
F.Nullary2(O.None[T], E.Of[error, O.Option[T]]),
|
||||
F.Flow2(
|
||||
@@ -52,7 +59,7 @@ func toOptionType[T any](item func(any) E.Either[error, T]) func(t any) E.Either
|
||||
// toIOEitherType converts an any to an IOEither[error, any] and then to an IOEither[error, T]
|
||||
func toIOEitherType[T any](item func(any) E.Either[error, T]) func(t any) E.Either[error, IOE.IOEither[error, T]] {
|
||||
return F.Flow2(
|
||||
toType[IOE.IOEither[error, any]](),
|
||||
toIOEitherAny,
|
||||
E.Map[error](IOE.ChainEitherK(item)),
|
||||
)
|
||||
}
|
||||
@@ -60,7 +67,7 @@ func toIOEitherType[T any](item func(any) E.Either[error, T]) func(t any) E.Eith
|
||||
// toIOOptionType converts an any to an IOOption[any] and then to an IOOption[T]
|
||||
func toIOOptionType[T any](item func(any) E.Either[error, T]) func(t any) E.Either[error, IOO.IOOption[T]] {
|
||||
return F.Flow2(
|
||||
toType[IOO.IOOption[any]](),
|
||||
toIOOptionAny,
|
||||
E.Map[error](IOO.ChainOptionK(F.Flow2(
|
||||
item,
|
||||
E.ToOption[error, T],
|
||||
@@ -71,7 +78,7 @@ func toIOOptionType[T any](item func(any) E.Either[error, T]) func(t any) E.Eith
|
||||
// toArrayType converts an any to a []T
|
||||
func toArrayType[T any](item func(any) E.Either[error, T]) func(t any) E.Either[error, []T] {
|
||||
return F.Flow2(
|
||||
toType[[]any](),
|
||||
toArrayAny,
|
||||
E.Chain(E.TraverseArray(item)),
|
||||
)
|
||||
}
|
||||
|
@@ -1,8 +1,10 @@
|
||||
package either
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
TST "github.com/IBM/fp-go/internal/testing"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -16,3 +18,33 @@ func TestCompactArray(t *testing.T) {
|
||||
res := CompactArray(ar)
|
||||
assert.Equal(t, 2, len(res))
|
||||
}
|
||||
|
||||
func TestSequenceArray(t *testing.T) {
|
||||
|
||||
s := TST.SequenceArrayTest(
|
||||
FromStrictEquals[error, bool](),
|
||||
Pointed[error, string](),
|
||||
Pointed[error, bool](),
|
||||
Functor[error, []string, bool](),
|
||||
SequenceArray[error, string],
|
||||
)
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
t.Run(fmt.Sprintf("TestSequenceArray %d", i), s(i))
|
||||
}
|
||||
}
|
||||
|
||||
func TestSequenceArrayError(t *testing.T) {
|
||||
|
||||
s := TST.SequenceArrayErrorTest(
|
||||
FromStrictEquals[error, bool](),
|
||||
Left[string, error],
|
||||
Left[bool, error],
|
||||
Pointed[error, string](),
|
||||
Pointed[error, bool](),
|
||||
Functor[error, []string, bool](),
|
||||
SequenceArray[error, string],
|
||||
)
|
||||
// run across four bits
|
||||
s(4)(t)
|
||||
}
|
||||
|
89
either/bind.go
Normal file
89
either/bind.go
Normal file
@@ -0,0 +1,89 @@
|
||||
// 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 either
|
||||
|
||||
import (
|
||||
A "github.com/IBM/fp-go/internal/apply"
|
||||
C "github.com/IBM/fp-go/internal/chain"
|
||||
F "github.com/IBM/fp-go/internal/functor"
|
||||
)
|
||||
|
||||
// Bind creates an empty context of type [S] to be used with the [Bind] operation
|
||||
func Do[E, S any](
|
||||
empty S,
|
||||
) Either[E, S] {
|
||||
return Of[E](empty)
|
||||
}
|
||||
|
||||
// Bind attaches the result of a computation to a context [S1] to produce a context [S2]
|
||||
func Bind[E, S1, S2, T any](
|
||||
setter func(T) func(S1) S2,
|
||||
f func(S1) Either[E, T],
|
||||
) func(Either[E, S1]) Either[E, S2] {
|
||||
return C.Bind(
|
||||
Chain[E, S1, S2],
|
||||
Map[E, T, S2],
|
||||
setter,
|
||||
f,
|
||||
)
|
||||
}
|
||||
|
||||
// Let attaches the result of a computation to a context [S1] to produce a context [S2]
|
||||
func Let[E, S1, S2, T any](
|
||||
key func(T) func(S1) S2,
|
||||
f func(S1) T,
|
||||
) func(Either[E, S1]) Either[E, S2] {
|
||||
return F.Let(
|
||||
Map[E, S1, S2],
|
||||
key,
|
||||
f,
|
||||
)
|
||||
}
|
||||
|
||||
// LetTo attaches the a value to a context [S1] to produce a context [S2]
|
||||
func LetTo[E, S1, S2, T any](
|
||||
key func(T) func(S1) S2,
|
||||
b T,
|
||||
) func(Either[E, S1]) Either[E, S2] {
|
||||
return F.LetTo(
|
||||
Map[E, S1, S2],
|
||||
key,
|
||||
b,
|
||||
)
|
||||
}
|
||||
|
||||
// BindTo initializes a new state [S1] from a value [T]
|
||||
func BindTo[E, S1, T any](
|
||||
setter func(T) S1,
|
||||
) func(Either[E, T]) Either[E, S1] {
|
||||
return C.BindTo(
|
||||
Map[E, T, S1],
|
||||
setter,
|
||||
)
|
||||
}
|
||||
|
||||
// ApS attaches a value to a context [S1] to produce a context [S2] by considering the context and the value concurrently
|
||||
func ApS[E, S1, S2, T any](
|
||||
setter func(T) func(S1) S2,
|
||||
fa Either[E, T],
|
||||
) func(Either[E, S1]) Either[E, S2] {
|
||||
return A.ApS(
|
||||
Ap[S2, E, T],
|
||||
Map[E, S1, func(T) S2],
|
||||
setter,
|
||||
fa,
|
||||
)
|
||||
}
|
56
either/bind_test.go
Normal file
56
either/bind_test.go
Normal 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 either
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
F "github.com/IBM/fp-go/function"
|
||||
"github.com/IBM/fp-go/internal/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func getLastName(s utils.Initial) Either[error, string] {
|
||||
return Of[error]("Doe")
|
||||
}
|
||||
|
||||
func getGivenName(s utils.WithLastName) Either[error, string] {
|
||||
return Of[error]("John")
|
||||
}
|
||||
|
||||
func TestBind(t *testing.T) {
|
||||
|
||||
res := F.Pipe3(
|
||||
Do[error](utils.Empty),
|
||||
Bind(utils.SetLastName, getLastName),
|
||||
Bind(utils.SetGivenName, getGivenName),
|
||||
Map[error](utils.GetFullName),
|
||||
)
|
||||
|
||||
assert.Equal(t, res, Of[error]("John Doe"))
|
||||
}
|
||||
|
||||
func TestApS(t *testing.T) {
|
||||
|
||||
res := F.Pipe3(
|
||||
Do[error](utils.Empty),
|
||||
ApS(utils.SetLastName, Of[error]("Doe")),
|
||||
ApS(utils.SetGivenName, Of[error]("John")),
|
||||
Map[error](utils.GetFullName),
|
||||
)
|
||||
|
||||
assert.Equal(t, res, Of[error]("John Doe"))
|
||||
}
|
@@ -20,30 +20,45 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
// Either defines a data structure that logically holds either an E or an A. The flag discriminates the cases
|
||||
Either[E, A any] struct {
|
||||
either struct {
|
||||
isLeft bool
|
||||
left E
|
||||
right A
|
||||
value any
|
||||
}
|
||||
|
||||
// Either defines a data structure that logically holds either an E or an A. The flag discriminates the cases
|
||||
Either[E, A any] either
|
||||
)
|
||||
|
||||
// String prints some debug info for the object
|
||||
func (s Either[E, A]) String() string {
|
||||
//
|
||||
// go:noinline
|
||||
func eitherString(s *either) string {
|
||||
if s.isLeft {
|
||||
return fmt.Sprintf("Left[%T, %T](%v)", s.left, s.right, s.left)
|
||||
return fmt.Sprintf("Left[%T](%v)", s.value, s.value)
|
||||
}
|
||||
return fmt.Sprintf("Right[%T, %T](%v)", s.left, s.right, s.right)
|
||||
return fmt.Sprintf("Right[%T](%v)", s.value, s.value)
|
||||
}
|
||||
|
||||
// Format prints some debug info for the object
|
||||
//
|
||||
// go:noinline
|
||||
func eitherFormat(e *either, f fmt.State, c rune) {
|
||||
switch c {
|
||||
case 's':
|
||||
fmt.Fprint(f, eitherString(e))
|
||||
default:
|
||||
fmt.Fprint(f, eitherString(e))
|
||||
}
|
||||
}
|
||||
|
||||
// String prints some debug info for the object
|
||||
func (s Either[E, A]) String() string {
|
||||
return eitherString((*either)(&s))
|
||||
}
|
||||
|
||||
// Format prints some debug info for the object
|
||||
func (s Either[E, A]) Format(f fmt.State, c rune) {
|
||||
switch c {
|
||||
case 's':
|
||||
fmt.Fprint(f, s.String())
|
||||
default:
|
||||
fmt.Fprint(f, s.String())
|
||||
}
|
||||
eitherFormat((*either)(&s), f, c)
|
||||
}
|
||||
|
||||
// IsLeft tests if the [Either] is a left value. Rather use [Fold] if you need to access the values. Inverse is [IsRight].
|
||||
@@ -58,23 +73,29 @@ func IsRight[E, A any](val Either[E, A]) bool {
|
||||
|
||||
// Left creates a new instance of an [Either] representing the left value.
|
||||
func Left[A, E any](value E) Either[E, A] {
|
||||
return Either[E, A]{isLeft: true, left: value}
|
||||
return Either[E, A]{true, value}
|
||||
}
|
||||
|
||||
// Right creates a new instance of an [Either] representing the right value.
|
||||
func Right[E, A any](value A) Either[E, A] {
|
||||
return Either[E, A]{isLeft: false, right: value}
|
||||
return Either[E, A]{false, value}
|
||||
}
|
||||
|
||||
// MonadFold extracts the values from an [Either] by invoking the [onLeft] callback or the [onRight] callback depending on the case
|
||||
func MonadFold[E, A, B any](ma Either[E, A], onLeft func(e E) B, onRight func(a A) B) B {
|
||||
if ma.isLeft {
|
||||
return onLeft(ma.left)
|
||||
return onLeft(ma.value.(E))
|
||||
}
|
||||
return onRight(ma.right)
|
||||
return onRight(ma.value.(A))
|
||||
}
|
||||
|
||||
// Unwrap converts an [Either] into the idiomatic tuple
|
||||
func Unwrap[E, A any](ma Either[E, A]) (A, E) {
|
||||
return ma.right, ma.left
|
||||
if ma.isLeft {
|
||||
var a A
|
||||
return a, ma.value.(E)
|
||||
} else {
|
||||
var e E
|
||||
return ma.value.(A), e
|
||||
}
|
||||
}
|
||||
|
@@ -16,4 +16,4 @@
|
||||
// Package option defines the [Either] datastructure and its monadic operations
|
||||
package either
|
||||
|
||||
//go:generate go run .. either --count 10 --filename gen.go
|
||||
//go:generate go run .. either --count 15 --filename gen.go
|
||||
|
@@ -22,6 +22,7 @@ package either
|
||||
import (
|
||||
E "github.com/IBM/fp-go/errors"
|
||||
F "github.com/IBM/fp-go/function"
|
||||
C "github.com/IBM/fp-go/internal/chain"
|
||||
FC "github.com/IBM/fp-go/internal/functor"
|
||||
L "github.com/IBM/fp-go/lazy"
|
||||
O "github.com/IBM/fp-go/option"
|
||||
@@ -32,7 +33,7 @@ func Of[E, A any](value A) Either[E, A] {
|
||||
return F.Pipe1(value, Right[E, A])
|
||||
}
|
||||
|
||||
func FromIO[E, IO ~func() A, A any](f IO) Either[E, A] {
|
||||
func FromIO[E any, IO ~func() A, A any](f IO) Either[E, A] {
|
||||
return F.Pipe1(f(), Right[E, A])
|
||||
}
|
||||
|
||||
@@ -64,19 +65,20 @@ func MonadMapTo[E, A, B any](fa Either[E, A], b B) Either[E, B] {
|
||||
}
|
||||
|
||||
func MapTo[E, A, B any](b B) func(Either[E, A]) Either[E, B] {
|
||||
return F.Bind2nd(MonadMapTo[E, A, B], b)
|
||||
return Map[E](F.Constant1[A](b))
|
||||
}
|
||||
|
||||
func MonadMapLeft[E, A, B any](fa Either[E, A], f func(E) B) Either[B, A] {
|
||||
return MonadFold(fa, F.Flow2(f, Left[A, B]), Right[B, A])
|
||||
func MonadMapLeft[E1, A, E2 any](fa Either[E1, A], f func(E1) E2) Either[E2, A] {
|
||||
return MonadFold(fa, F.Flow2(f, Left[A, E2]), Right[E2, A])
|
||||
}
|
||||
|
||||
func Map[E, A, B any](f func(a A) B) func(fa Either[E, A]) Either[E, B] {
|
||||
return Chain(F.Flow2(f, Right[E, B]))
|
||||
}
|
||||
|
||||
func MapLeft[E, A, B any](f func(E) B) func(fa Either[E, A]) Either[B, A] {
|
||||
return F.Bind2nd(MonadMapLeft[E, A, B], f)
|
||||
// MapLeft applies a mapping function to the error channel
|
||||
func MapLeft[A, E1, E2 any](f func(E1) E2) func(fa Either[E1, A]) Either[E2, A] {
|
||||
return Fold(F.Flow2(f, Left[A, E2]), Right[E2, A])
|
||||
}
|
||||
|
||||
func MonadChain[E, A, B any](fa Either[E, A], f func(a A) Either[E, B]) Either[E, B] {
|
||||
@@ -84,12 +86,15 @@ func MonadChain[E, A, B any](fa Either[E, A], f func(a A) Either[E, B]) Either[E
|
||||
}
|
||||
|
||||
func MonadChainFirst[E, A, B any](ma Either[E, A], f func(a A) Either[E, B]) Either[E, A] {
|
||||
return MonadChain(ma, func(a A) Either[E, A] {
|
||||
return MonadMap(f(a), F.Constant1[B](a))
|
||||
})
|
||||
return C.MonadChainFirst(
|
||||
MonadChain[E, A, A],
|
||||
MonadMap[E, B, A],
|
||||
ma,
|
||||
f,
|
||||
)
|
||||
}
|
||||
|
||||
func MonadChainTo[A, E, B any](ma Either[E, A], mb Either[E, B]) Either[E, B] {
|
||||
func MonadChainTo[A, E, B any](_ Either[E, A], mb Either[E, B]) Either[E, B] {
|
||||
return mb
|
||||
}
|
||||
|
||||
@@ -105,15 +110,19 @@ func ChainOptionK[A, B, E any](onNone func() E) func(func(A) O.Option[B]) func(E
|
||||
}
|
||||
|
||||
func ChainTo[A, E, B any](mb Either[E, B]) func(Either[E, A]) Either[E, B] {
|
||||
return F.Bind2nd(MonadChainTo[A, E, B], mb)
|
||||
return F.Constant1[Either[E, A]](mb)
|
||||
}
|
||||
|
||||
func Chain[E, A, B any](f func(a A) Either[E, B]) func(Either[E, A]) Either[E, B] {
|
||||
return F.Bind2nd(MonadChain[E, A, B], f)
|
||||
return Fold(Left[B, E], f)
|
||||
}
|
||||
|
||||
func ChainFirst[E, A, B any](f func(a A) Either[E, B]) func(Either[E, A]) Either[E, A] {
|
||||
return F.Bind2nd(MonadChainFirst[E, A, B], f)
|
||||
return C.ChainFirst(
|
||||
Chain[E, A, A],
|
||||
Map[E, B, A],
|
||||
f,
|
||||
)
|
||||
}
|
||||
|
||||
func Flatten[E, A any](mma Either[E, Either[E, A]]) Either[E, A] {
|
||||
@@ -250,7 +259,7 @@ func MonadFlap[E, B, A any](fab Either[E, func(A) B], a A) Either[E, B] {
|
||||
}
|
||||
|
||||
func Flap[E, B, A any](a A) func(Either[E, func(A) B]) Either[E, B] {
|
||||
return F.Bind2nd(MonadFlap[E, B, A], a)
|
||||
return FC.Flap(Map[E, func(A) B, B], a)
|
||||
}
|
||||
|
||||
func MonadAlt[E, A any](fa Either[E, A], that L.Lazy[Either[E, A]]) Either[E, A] {
|
||||
|
@@ -17,21 +17,17 @@ package either
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
F "github.com/IBM/fp-go/function"
|
||||
"github.com/IBM/fp-go/internal/utils"
|
||||
IO "github.com/IBM/fp-go/io"
|
||||
O "github.com/IBM/fp-go/option"
|
||||
S "github.com/IBM/fp-go/string"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestDefault(t *testing.T) {
|
||||
var e Either[error, string]
|
||||
|
||||
assert.Equal(t, Of[error](""), e)
|
||||
}
|
||||
|
||||
func TestIsLeft(t *testing.T) {
|
||||
err := errors.New("Some error")
|
||||
withError := Left[string](err)
|
||||
@@ -76,7 +72,6 @@ func TestReduce(t *testing.T) {
|
||||
assert.Equal(t, "foo", F.Pipe1(Left[string, string]("bar"), Reduce[string](s.Concat, "foo")))
|
||||
|
||||
}
|
||||
|
||||
func TestAp(t *testing.T) {
|
||||
f := S.Size
|
||||
|
||||
@@ -115,3 +110,20 @@ func TestFromOption(t *testing.T) {
|
||||
assert.Equal(t, Left[int]("none"), FromOption[int](F.Constant("none"))(O.None[int]()))
|
||||
assert.Equal(t, Right[string](1), FromOption[int](F.Constant("none"))(O.Some(1)))
|
||||
}
|
||||
|
||||
func TestStringer(t *testing.T) {
|
||||
e := Of[error]("foo")
|
||||
exp := "Right[string](foo)"
|
||||
|
||||
assert.Equal(t, exp, e.String())
|
||||
|
||||
var s fmt.Stringer = e
|
||||
assert.Equal(t, exp, s.String())
|
||||
}
|
||||
|
||||
func TestFromIO(t *testing.T) {
|
||||
f := IO.Of("abc")
|
||||
e := FromIO[error](f)
|
||||
|
||||
assert.Equal(t, Right[error]("abc"), e)
|
||||
}
|
||||
|
@@ -34,7 +34,7 @@ func Eq[E, A any](e EQ.Eq[E], a EQ.Eq[A]) EQ.Eq[Either[E, A]] {
|
||||
return EQ.FromEquals(F.Uncurry2(fld))
|
||||
}
|
||||
|
||||
// FromStrictEquals constructs an `Eq` from the canonical comparison function
|
||||
// FromStrictEquals constructs an [EQ.Eq] from the canonical comparison function
|
||||
func FromStrictEquals[E, A comparable]() EQ.Eq[Either[E, A]] {
|
||||
return Eq(EQ.FromStrictEquals[E](), EQ.FromStrictEquals[A]())
|
||||
}
|
||||
|
@@ -48,11 +48,11 @@ func ExampleEither_creation() {
|
||||
fmt.Println(rightFromPred)
|
||||
|
||||
// Output:
|
||||
// Left[*errors.errorString, string](some error)
|
||||
// Right[<nil>, string](value)
|
||||
// Left[*errors.errorString, *string](value was nil)
|
||||
// Left[*errors.errorString](some error)
|
||||
// Right[string](value)
|
||||
// Left[*errors.errorString](value was nil)
|
||||
// true
|
||||
// Left[*errors.errorString, int](3 is an odd number)
|
||||
// Right[<nil>, int](4)
|
||||
// Left[*errors.errorString](3 is an odd number)
|
||||
// Right[int](4)
|
||||
|
||||
}
|
||||
|
@@ -53,8 +53,8 @@ func ExampleEither_extraction() {
|
||||
fmt.Println(doubleFromRightBis)
|
||||
|
||||
// Output:
|
||||
// Left[*errors.errorString, int](Division by Zero!)
|
||||
// Right[<nil>, int](10)
|
||||
// Left[*errors.errorString](Division by Zero!)
|
||||
// Right[int](10)
|
||||
// 0
|
||||
// 10
|
||||
// 0
|
||||
|
31
either/functor.go
Normal file
31
either/functor.go
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2024 IBM Corp.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package either
|
||||
|
||||
import (
|
||||
"github.com/IBM/fp-go/internal/functor"
|
||||
)
|
||||
|
||||
type eitherFunctor[E, A, B any] struct{}
|
||||
|
||||
func (o *eitherFunctor[E, A, B]) Map(f func(A) B) func(Either[E, A]) Either[E, B] {
|
||||
return Map[E, A, B](f)
|
||||
}
|
||||
|
||||
// Functor implements the functoric operations for [Either]
|
||||
func Functor[E, A, B any]() functor.Functor[A, B, Either[E, A], Either[E, B]] {
|
||||
return &eitherFunctor[E, A, B]{}
|
||||
}
|
517
either/gen.go
517
either/gen.go
@@ -1,6 +1,6 @@
|
||||
// Code generated by go generate; DO NOT EDIT.
|
||||
// This file was generated by robots at
|
||||
// 2023-10-23 08:30:40.410373 +0200 CEST m=+0.010337601
|
||||
// 2024-02-29 16:18:50.8721435 +0100 CET m=+0.070394501
|
||||
|
||||
package either
|
||||
|
||||
@@ -679,3 +679,518 @@ func TraverseTuple10[F1 ~func(A1) Either[E, T1], F2 ~func(A2) Either[E, T2], F3
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Eitherize11 converts a function with 11 parameters returning a tuple into a function with 11 parameters returning an Either
|
||||
// The inverse function is [Uneitherize11]
|
||||
func Eitherize11[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) (R, error), T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) Either[error, R] {
|
||||
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10) Either[error, R] {
|
||||
return TryCatchError(f(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10))
|
||||
}
|
||||
}
|
||||
|
||||
// Uneitherize11 converts a function with 11 parameters returning an Either into a function with 11 parameters returning a tuple
|
||||
// The inverse function is [Eitherize11]
|
||||
func Uneitherize11[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) Either[error, R], T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) (R, error) {
|
||||
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10) (R, error) {
|
||||
return UnwrapError(f(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10))
|
||||
}
|
||||
}
|
||||
|
||||
// SequenceT11 converts 11 parameters of [Either[E, T]] into a [Either[E, Tuple11]].
|
||||
func SequenceT11[E, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 any](t1 Either[E, T1], t2 Either[E, T2], t3 Either[E, T3], t4 Either[E, T4], t5 Either[E, T5], t6 Either[E, T6], t7 Either[E, T7], t8 Either[E, T8], t9 Either[E, T9], t10 Either[E, T10], t11 Either[E, T11]) Either[E, T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]] {
|
||||
return A.SequenceT11(
|
||||
Map[E, T1, func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]],
|
||||
Ap[func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T2],
|
||||
Ap[func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T3],
|
||||
Ap[func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T4],
|
||||
Ap[func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T5],
|
||||
Ap[func(T7) func(T8) func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T6],
|
||||
Ap[func(T8) func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T7],
|
||||
Ap[func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T8],
|
||||
Ap[func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T9],
|
||||
Ap[func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T10],
|
||||
Ap[T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T11],
|
||||
t1,
|
||||
t2,
|
||||
t3,
|
||||
t4,
|
||||
t5,
|
||||
t6,
|
||||
t7,
|
||||
t8,
|
||||
t9,
|
||||
t10,
|
||||
t11,
|
||||
)
|
||||
}
|
||||
|
||||
// SequenceTuple11 converts a [Tuple11] of [Either[E, T]] into an [Either[E, Tuple11]].
|
||||
func SequenceTuple11[E, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 any](t T.Tuple11[Either[E, T1], Either[E, T2], Either[E, T3], Either[E, T4], Either[E, T5], Either[E, T6], Either[E, T7], Either[E, T8], Either[E, T9], Either[E, T10], Either[E, T11]]) Either[E, T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]] {
|
||||
return A.SequenceTuple11(
|
||||
Map[E, T1, func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]],
|
||||
Ap[func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T2],
|
||||
Ap[func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T3],
|
||||
Ap[func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T4],
|
||||
Ap[func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T5],
|
||||
Ap[func(T7) func(T8) func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T6],
|
||||
Ap[func(T8) func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T7],
|
||||
Ap[func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T8],
|
||||
Ap[func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T9],
|
||||
Ap[func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T10],
|
||||
Ap[T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T11],
|
||||
t,
|
||||
)
|
||||
}
|
||||
|
||||
// TraverseTuple11 converts a [Tuple11] of [A] via transformation functions transforming [A] to [Either[E, A]] into a [Either[E, Tuple11]].
|
||||
func TraverseTuple11[F1 ~func(A1) Either[E, T1], F2 ~func(A2) Either[E, T2], F3 ~func(A3) Either[E, T3], F4 ~func(A4) Either[E, T4], F5 ~func(A5) Either[E, T5], F6 ~func(A6) Either[E, T6], F7 ~func(A7) Either[E, T7], F8 ~func(A8) Either[E, T8], F9 ~func(A9) Either[E, T9], F10 ~func(A10) Either[E, T10], F11 ~func(A11) Either[E, T11], E, A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8, A9, T9, A10, T10, A11, T11 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11) func(T.Tuple11[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11]) Either[E, T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]] {
|
||||
return func(t T.Tuple11[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11]) Either[E, T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]] {
|
||||
return A.TraverseTuple11(
|
||||
Map[E, T1, func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]],
|
||||
Ap[func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T2],
|
||||
Ap[func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T3],
|
||||
Ap[func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T4],
|
||||
Ap[func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T5],
|
||||
Ap[func(T7) func(T8) func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T6],
|
||||
Ap[func(T8) func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T7],
|
||||
Ap[func(T9) func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T8],
|
||||
Ap[func(T10) func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T9],
|
||||
Ap[func(T11) T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T10],
|
||||
Ap[T.Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], E, T11],
|
||||
f1,
|
||||
f2,
|
||||
f3,
|
||||
f4,
|
||||
f5,
|
||||
f6,
|
||||
f7,
|
||||
f8,
|
||||
f9,
|
||||
f10,
|
||||
f11,
|
||||
t,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Eitherize12 converts a function with 12 parameters returning a tuple into a function with 12 parameters returning an Either
|
||||
// The inverse function is [Uneitherize12]
|
||||
func Eitherize12[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) (R, error), T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) Either[error, R] {
|
||||
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10, t11 T11) Either[error, R] {
|
||||
return TryCatchError(f(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11))
|
||||
}
|
||||
}
|
||||
|
||||
// Uneitherize12 converts a function with 12 parameters returning an Either into a function with 12 parameters returning a tuple
|
||||
// The inverse function is [Eitherize12]
|
||||
func Uneitherize12[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) Either[error, R], T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) (R, error) {
|
||||
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10, t11 T11) (R, error) {
|
||||
return UnwrapError(f(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11))
|
||||
}
|
||||
}
|
||||
|
||||
// SequenceT12 converts 12 parameters of [Either[E, T]] into a [Either[E, Tuple12]].
|
||||
func SequenceT12[E, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 any](t1 Either[E, T1], t2 Either[E, T2], t3 Either[E, T3], t4 Either[E, T4], t5 Either[E, T5], t6 Either[E, T6], t7 Either[E, T7], t8 Either[E, T8], t9 Either[E, T9], t10 Either[E, T10], t11 Either[E, T11], t12 Either[E, T12]) Either[E, T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]] {
|
||||
return A.SequenceT12(
|
||||
Map[E, T1, func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]],
|
||||
Ap[func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T2],
|
||||
Ap[func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T3],
|
||||
Ap[func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T4],
|
||||
Ap[func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T5],
|
||||
Ap[func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T6],
|
||||
Ap[func(T8) func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T7],
|
||||
Ap[func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T8],
|
||||
Ap[func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T9],
|
||||
Ap[func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T10],
|
||||
Ap[func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T11],
|
||||
Ap[T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T12],
|
||||
t1,
|
||||
t2,
|
||||
t3,
|
||||
t4,
|
||||
t5,
|
||||
t6,
|
||||
t7,
|
||||
t8,
|
||||
t9,
|
||||
t10,
|
||||
t11,
|
||||
t12,
|
||||
)
|
||||
}
|
||||
|
||||
// SequenceTuple12 converts a [Tuple12] of [Either[E, T]] into an [Either[E, Tuple12]].
|
||||
func SequenceTuple12[E, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 any](t T.Tuple12[Either[E, T1], Either[E, T2], Either[E, T3], Either[E, T4], Either[E, T5], Either[E, T6], Either[E, T7], Either[E, T8], Either[E, T9], Either[E, T10], Either[E, T11], Either[E, T12]]) Either[E, T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]] {
|
||||
return A.SequenceTuple12(
|
||||
Map[E, T1, func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]],
|
||||
Ap[func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T2],
|
||||
Ap[func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T3],
|
||||
Ap[func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T4],
|
||||
Ap[func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T5],
|
||||
Ap[func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T6],
|
||||
Ap[func(T8) func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T7],
|
||||
Ap[func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T8],
|
||||
Ap[func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T9],
|
||||
Ap[func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T10],
|
||||
Ap[func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T11],
|
||||
Ap[T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T12],
|
||||
t,
|
||||
)
|
||||
}
|
||||
|
||||
// TraverseTuple12 converts a [Tuple12] of [A] via transformation functions transforming [A] to [Either[E, A]] into a [Either[E, Tuple12]].
|
||||
func TraverseTuple12[F1 ~func(A1) Either[E, T1], F2 ~func(A2) Either[E, T2], F3 ~func(A3) Either[E, T3], F4 ~func(A4) Either[E, T4], F5 ~func(A5) Either[E, T5], F6 ~func(A6) Either[E, T6], F7 ~func(A7) Either[E, T7], F8 ~func(A8) Either[E, T8], F9 ~func(A9) Either[E, T9], F10 ~func(A10) Either[E, T10], F11 ~func(A11) Either[E, T11], F12 ~func(A12) Either[E, T12], E, A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8, A9, T9, A10, T10, A11, T11, A12, T12 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12) func(T.Tuple12[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12]) Either[E, T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]] {
|
||||
return func(t T.Tuple12[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12]) Either[E, T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]] {
|
||||
return A.TraverseTuple12(
|
||||
Map[E, T1, func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]],
|
||||
Ap[func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T2],
|
||||
Ap[func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T3],
|
||||
Ap[func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T4],
|
||||
Ap[func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T5],
|
||||
Ap[func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T6],
|
||||
Ap[func(T8) func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T7],
|
||||
Ap[func(T9) func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T8],
|
||||
Ap[func(T10) func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T9],
|
||||
Ap[func(T11) func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T10],
|
||||
Ap[func(T12) T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T11],
|
||||
Ap[T.Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], E, T12],
|
||||
f1,
|
||||
f2,
|
||||
f3,
|
||||
f4,
|
||||
f5,
|
||||
f6,
|
||||
f7,
|
||||
f8,
|
||||
f9,
|
||||
f10,
|
||||
f11,
|
||||
f12,
|
||||
t,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Eitherize13 converts a function with 13 parameters returning a tuple into a function with 13 parameters returning an Either
|
||||
// The inverse function is [Uneitherize13]
|
||||
func Eitherize13[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) (R, error), T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) Either[error, R] {
|
||||
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10, t11 T11, t12 T12) Either[error, R] {
|
||||
return TryCatchError(f(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12))
|
||||
}
|
||||
}
|
||||
|
||||
// Uneitherize13 converts a function with 13 parameters returning an Either into a function with 13 parameters returning a tuple
|
||||
// The inverse function is [Eitherize13]
|
||||
func Uneitherize13[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) Either[error, R], T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) (R, error) {
|
||||
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10, t11 T11, t12 T12) (R, error) {
|
||||
return UnwrapError(f(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12))
|
||||
}
|
||||
}
|
||||
|
||||
// SequenceT13 converts 13 parameters of [Either[E, T]] into a [Either[E, Tuple13]].
|
||||
func SequenceT13[E, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 any](t1 Either[E, T1], t2 Either[E, T2], t3 Either[E, T3], t4 Either[E, T4], t5 Either[E, T5], t6 Either[E, T6], t7 Either[E, T7], t8 Either[E, T8], t9 Either[E, T9], t10 Either[E, T10], t11 Either[E, T11], t12 Either[E, T12], t13 Either[E, T13]) Either[E, T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]] {
|
||||
return A.SequenceT13(
|
||||
Map[E, T1, func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]],
|
||||
Ap[func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T2],
|
||||
Ap[func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T3],
|
||||
Ap[func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T4],
|
||||
Ap[func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T5],
|
||||
Ap[func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T6],
|
||||
Ap[func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T7],
|
||||
Ap[func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T8],
|
||||
Ap[func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T9],
|
||||
Ap[func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T10],
|
||||
Ap[func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T11],
|
||||
Ap[func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T12],
|
||||
Ap[T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T13],
|
||||
t1,
|
||||
t2,
|
||||
t3,
|
||||
t4,
|
||||
t5,
|
||||
t6,
|
||||
t7,
|
||||
t8,
|
||||
t9,
|
||||
t10,
|
||||
t11,
|
||||
t12,
|
||||
t13,
|
||||
)
|
||||
}
|
||||
|
||||
// SequenceTuple13 converts a [Tuple13] of [Either[E, T]] into an [Either[E, Tuple13]].
|
||||
func SequenceTuple13[E, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 any](t T.Tuple13[Either[E, T1], Either[E, T2], Either[E, T3], Either[E, T4], Either[E, T5], Either[E, T6], Either[E, T7], Either[E, T8], Either[E, T9], Either[E, T10], Either[E, T11], Either[E, T12], Either[E, T13]]) Either[E, T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]] {
|
||||
return A.SequenceTuple13(
|
||||
Map[E, T1, func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]],
|
||||
Ap[func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T2],
|
||||
Ap[func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T3],
|
||||
Ap[func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T4],
|
||||
Ap[func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T5],
|
||||
Ap[func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T6],
|
||||
Ap[func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T7],
|
||||
Ap[func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T8],
|
||||
Ap[func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T9],
|
||||
Ap[func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T10],
|
||||
Ap[func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T11],
|
||||
Ap[func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T12],
|
||||
Ap[T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T13],
|
||||
t,
|
||||
)
|
||||
}
|
||||
|
||||
// TraverseTuple13 converts a [Tuple13] of [A] via transformation functions transforming [A] to [Either[E, A]] into a [Either[E, Tuple13]].
|
||||
func TraverseTuple13[F1 ~func(A1) Either[E, T1], F2 ~func(A2) Either[E, T2], F3 ~func(A3) Either[E, T3], F4 ~func(A4) Either[E, T4], F5 ~func(A5) Either[E, T5], F6 ~func(A6) Either[E, T6], F7 ~func(A7) Either[E, T7], F8 ~func(A8) Either[E, T8], F9 ~func(A9) Either[E, T9], F10 ~func(A10) Either[E, T10], F11 ~func(A11) Either[E, T11], F12 ~func(A12) Either[E, T12], F13 ~func(A13) Either[E, T13], E, A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8, A9, T9, A10, T10, A11, T11, A12, T12, A13, T13 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13) func(T.Tuple13[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13]) Either[E, T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]] {
|
||||
return func(t T.Tuple13[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13]) Either[E, T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]] {
|
||||
return A.TraverseTuple13(
|
||||
Map[E, T1, func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]],
|
||||
Ap[func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T2],
|
||||
Ap[func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T3],
|
||||
Ap[func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T4],
|
||||
Ap[func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T5],
|
||||
Ap[func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T6],
|
||||
Ap[func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T7],
|
||||
Ap[func(T9) func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T8],
|
||||
Ap[func(T10) func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T9],
|
||||
Ap[func(T11) func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T10],
|
||||
Ap[func(T12) func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T11],
|
||||
Ap[func(T13) T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T12],
|
||||
Ap[T.Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], E, T13],
|
||||
f1,
|
||||
f2,
|
||||
f3,
|
||||
f4,
|
||||
f5,
|
||||
f6,
|
||||
f7,
|
||||
f8,
|
||||
f9,
|
||||
f10,
|
||||
f11,
|
||||
f12,
|
||||
f13,
|
||||
t,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Eitherize14 converts a function with 14 parameters returning a tuple into a function with 14 parameters returning an Either
|
||||
// The inverse function is [Uneitherize14]
|
||||
func Eitherize14[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) (R, error), T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) Either[error, R] {
|
||||
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10, t11 T11, t12 T12, t13 T13) Either[error, R] {
|
||||
return TryCatchError(f(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13))
|
||||
}
|
||||
}
|
||||
|
||||
// Uneitherize14 converts a function with 14 parameters returning an Either into a function with 14 parameters returning a tuple
|
||||
// The inverse function is [Eitherize14]
|
||||
func Uneitherize14[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) Either[error, R], T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) (R, error) {
|
||||
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10, t11 T11, t12 T12, t13 T13) (R, error) {
|
||||
return UnwrapError(f(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13))
|
||||
}
|
||||
}
|
||||
|
||||
// SequenceT14 converts 14 parameters of [Either[E, T]] into a [Either[E, Tuple14]].
|
||||
func SequenceT14[E, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 any](t1 Either[E, T1], t2 Either[E, T2], t3 Either[E, T3], t4 Either[E, T4], t5 Either[E, T5], t6 Either[E, T6], t7 Either[E, T7], t8 Either[E, T8], t9 Either[E, T9], t10 Either[E, T10], t11 Either[E, T11], t12 Either[E, T12], t13 Either[E, T13], t14 Either[E, T14]) Either[E, T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]] {
|
||||
return A.SequenceT14(
|
||||
Map[E, T1, func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]],
|
||||
Ap[func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T2],
|
||||
Ap[func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T3],
|
||||
Ap[func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T4],
|
||||
Ap[func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T5],
|
||||
Ap[func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T6],
|
||||
Ap[func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T7],
|
||||
Ap[func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T8],
|
||||
Ap[func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T9],
|
||||
Ap[func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T10],
|
||||
Ap[func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T11],
|
||||
Ap[func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T12],
|
||||
Ap[func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T13],
|
||||
Ap[T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T14],
|
||||
t1,
|
||||
t2,
|
||||
t3,
|
||||
t4,
|
||||
t5,
|
||||
t6,
|
||||
t7,
|
||||
t8,
|
||||
t9,
|
||||
t10,
|
||||
t11,
|
||||
t12,
|
||||
t13,
|
||||
t14,
|
||||
)
|
||||
}
|
||||
|
||||
// SequenceTuple14 converts a [Tuple14] of [Either[E, T]] into an [Either[E, Tuple14]].
|
||||
func SequenceTuple14[E, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 any](t T.Tuple14[Either[E, T1], Either[E, T2], Either[E, T3], Either[E, T4], Either[E, T5], Either[E, T6], Either[E, T7], Either[E, T8], Either[E, T9], Either[E, T10], Either[E, T11], Either[E, T12], Either[E, T13], Either[E, T14]]) Either[E, T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]] {
|
||||
return A.SequenceTuple14(
|
||||
Map[E, T1, func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]],
|
||||
Ap[func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T2],
|
||||
Ap[func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T3],
|
||||
Ap[func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T4],
|
||||
Ap[func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T5],
|
||||
Ap[func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T6],
|
||||
Ap[func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T7],
|
||||
Ap[func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T8],
|
||||
Ap[func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T9],
|
||||
Ap[func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T10],
|
||||
Ap[func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T11],
|
||||
Ap[func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T12],
|
||||
Ap[func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T13],
|
||||
Ap[T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T14],
|
||||
t,
|
||||
)
|
||||
}
|
||||
|
||||
// TraverseTuple14 converts a [Tuple14] of [A] via transformation functions transforming [A] to [Either[E, A]] into a [Either[E, Tuple14]].
|
||||
func TraverseTuple14[F1 ~func(A1) Either[E, T1], F2 ~func(A2) Either[E, T2], F3 ~func(A3) Either[E, T3], F4 ~func(A4) Either[E, T4], F5 ~func(A5) Either[E, T5], F6 ~func(A6) Either[E, T6], F7 ~func(A7) Either[E, T7], F8 ~func(A8) Either[E, T8], F9 ~func(A9) Either[E, T9], F10 ~func(A10) Either[E, T10], F11 ~func(A11) Either[E, T11], F12 ~func(A12) Either[E, T12], F13 ~func(A13) Either[E, T13], F14 ~func(A14) Either[E, T14], E, A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8, A9, T9, A10, T10, A11, T11, A12, T12, A13, T13, A14, T14 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13, f14 F14) func(T.Tuple14[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14]) Either[E, T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]] {
|
||||
return func(t T.Tuple14[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14]) Either[E, T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]] {
|
||||
return A.TraverseTuple14(
|
||||
Map[E, T1, func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]],
|
||||
Ap[func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T2],
|
||||
Ap[func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T3],
|
||||
Ap[func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T4],
|
||||
Ap[func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T5],
|
||||
Ap[func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T6],
|
||||
Ap[func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T7],
|
||||
Ap[func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T8],
|
||||
Ap[func(T10) func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T9],
|
||||
Ap[func(T11) func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T10],
|
||||
Ap[func(T12) func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T11],
|
||||
Ap[func(T13) func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T12],
|
||||
Ap[func(T14) T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T13],
|
||||
Ap[T.Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], E, T14],
|
||||
f1,
|
||||
f2,
|
||||
f3,
|
||||
f4,
|
||||
f5,
|
||||
f6,
|
||||
f7,
|
||||
f8,
|
||||
f9,
|
||||
f10,
|
||||
f11,
|
||||
f12,
|
||||
f13,
|
||||
f14,
|
||||
t,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Eitherize15 converts a function with 15 parameters returning a tuple into a function with 15 parameters returning an Either
|
||||
// The inverse function is [Uneitherize15]
|
||||
func Eitherize15[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) (R, error), T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) Either[error, R] {
|
||||
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10, t11 T11, t12 T12, t13 T13, t14 T14) Either[error, R] {
|
||||
return TryCatchError(f(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14))
|
||||
}
|
||||
}
|
||||
|
||||
// Uneitherize15 converts a function with 15 parameters returning an Either into a function with 15 parameters returning a tuple
|
||||
// The inverse function is [Eitherize15]
|
||||
func Uneitherize15[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) Either[error, R], T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) (R, error) {
|
||||
return func(t0 T0, t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10, t11 T11, t12 T12, t13 T13, t14 T14) (R, error) {
|
||||
return UnwrapError(f(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14))
|
||||
}
|
||||
}
|
||||
|
||||
// SequenceT15 converts 15 parameters of [Either[E, T]] into a [Either[E, Tuple15]].
|
||||
func SequenceT15[E, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 any](t1 Either[E, T1], t2 Either[E, T2], t3 Either[E, T3], t4 Either[E, T4], t5 Either[E, T5], t6 Either[E, T6], t7 Either[E, T7], t8 Either[E, T8], t9 Either[E, T9], t10 Either[E, T10], t11 Either[E, T11], t12 Either[E, T12], t13 Either[E, T13], t14 Either[E, T14], t15 Either[E, T15]) Either[E, T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]] {
|
||||
return A.SequenceT15(
|
||||
Map[E, T1, func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]],
|
||||
Ap[func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T2],
|
||||
Ap[func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T3],
|
||||
Ap[func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T4],
|
||||
Ap[func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T5],
|
||||
Ap[func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T6],
|
||||
Ap[func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T7],
|
||||
Ap[func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T8],
|
||||
Ap[func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T9],
|
||||
Ap[func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T10],
|
||||
Ap[func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T11],
|
||||
Ap[func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T12],
|
||||
Ap[func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T13],
|
||||
Ap[func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T14],
|
||||
Ap[T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T15],
|
||||
t1,
|
||||
t2,
|
||||
t3,
|
||||
t4,
|
||||
t5,
|
||||
t6,
|
||||
t7,
|
||||
t8,
|
||||
t9,
|
||||
t10,
|
||||
t11,
|
||||
t12,
|
||||
t13,
|
||||
t14,
|
||||
t15,
|
||||
)
|
||||
}
|
||||
|
||||
// SequenceTuple15 converts a [Tuple15] of [Either[E, T]] into an [Either[E, Tuple15]].
|
||||
func SequenceTuple15[E, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 any](t T.Tuple15[Either[E, T1], Either[E, T2], Either[E, T3], Either[E, T4], Either[E, T5], Either[E, T6], Either[E, T7], Either[E, T8], Either[E, T9], Either[E, T10], Either[E, T11], Either[E, T12], Either[E, T13], Either[E, T14], Either[E, T15]]) Either[E, T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]] {
|
||||
return A.SequenceTuple15(
|
||||
Map[E, T1, func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]],
|
||||
Ap[func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T2],
|
||||
Ap[func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T3],
|
||||
Ap[func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T4],
|
||||
Ap[func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T5],
|
||||
Ap[func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T6],
|
||||
Ap[func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T7],
|
||||
Ap[func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T8],
|
||||
Ap[func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T9],
|
||||
Ap[func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T10],
|
||||
Ap[func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T11],
|
||||
Ap[func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T12],
|
||||
Ap[func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T13],
|
||||
Ap[func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T14],
|
||||
Ap[T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T15],
|
||||
t,
|
||||
)
|
||||
}
|
||||
|
||||
// TraverseTuple15 converts a [Tuple15] of [A] via transformation functions transforming [A] to [Either[E, A]] into a [Either[E, Tuple15]].
|
||||
func TraverseTuple15[F1 ~func(A1) Either[E, T1], F2 ~func(A2) Either[E, T2], F3 ~func(A3) Either[E, T3], F4 ~func(A4) Either[E, T4], F5 ~func(A5) Either[E, T5], F6 ~func(A6) Either[E, T6], F7 ~func(A7) Either[E, T7], F8 ~func(A8) Either[E, T8], F9 ~func(A9) Either[E, T9], F10 ~func(A10) Either[E, T10], F11 ~func(A11) Either[E, T11], F12 ~func(A12) Either[E, T12], F13 ~func(A13) Either[E, T13], F14 ~func(A14) Either[E, T14], F15 ~func(A15) Either[E, T15], E, A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8, A9, T9, A10, T10, A11, T11, A12, T12, A13, T13, A14, T14, A15, T15 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10, f11 F11, f12 F12, f13 F13, f14 F14, f15 F15) func(T.Tuple15[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15]) Either[E, T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]] {
|
||||
return func(t T.Tuple15[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15]) Either[E, T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]] {
|
||||
return A.TraverseTuple15(
|
||||
Map[E, T1, func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]],
|
||||
Ap[func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T2],
|
||||
Ap[func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T3],
|
||||
Ap[func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T4],
|
||||
Ap[func(T6) func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T5],
|
||||
Ap[func(T7) func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T6],
|
||||
Ap[func(T8) func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T7],
|
||||
Ap[func(T9) func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T8],
|
||||
Ap[func(T10) func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T9],
|
||||
Ap[func(T11) func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T10],
|
||||
Ap[func(T12) func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T11],
|
||||
Ap[func(T13) func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T12],
|
||||
Ap[func(T14) func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T13],
|
||||
Ap[func(T15) T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T14],
|
||||
Ap[T.Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], E, T15],
|
||||
f1,
|
||||
f2,
|
||||
f3,
|
||||
f4,
|
||||
f5,
|
||||
f6,
|
||||
f7,
|
||||
f8,
|
||||
f9,
|
||||
f10,
|
||||
f11,
|
||||
f12,
|
||||
f13,
|
||||
f14,
|
||||
f15,
|
||||
t,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
43
either/monad.go
Normal file
43
either/monad.go
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2024 IBM Corp.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package either
|
||||
|
||||
import (
|
||||
"github.com/IBM/fp-go/internal/monad"
|
||||
)
|
||||
|
||||
type eitherMonad[E, A, B any] struct{}
|
||||
|
||||
func (o *eitherMonad[E, A, B]) Of(a A) Either[E, A] {
|
||||
return Of[E, A](a)
|
||||
}
|
||||
|
||||
func (o *eitherMonad[E, A, B]) Map(f func(A) B) func(Either[E, A]) Either[E, B] {
|
||||
return Map[E, A, B](f)
|
||||
}
|
||||
|
||||
func (o *eitherMonad[E, A, B]) Chain(f func(A) Either[E, B]) func(Either[E, A]) Either[E, B] {
|
||||
return Chain[E, A, B](f)
|
||||
}
|
||||
|
||||
func (o *eitherMonad[E, A, B]) Ap(fa Either[E, A]) func(Either[E, func(A) B]) Either[E, B] {
|
||||
return Ap[B, E, A](fa)
|
||||
}
|
||||
|
||||
// Monad implements the monadic operations for [Either]
|
||||
func Monad[E, A, B any]() monad.Monad[A, B, Either[E, A], Either[E, B], Either[E, func(A) B]] {
|
||||
return &eitherMonad[E, A, B]{}
|
||||
}
|
31
either/pointed.go
Normal file
31
either/pointed.go
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2024 IBM Corp.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package either
|
||||
|
||||
import (
|
||||
"github.com/IBM/fp-go/internal/pointed"
|
||||
)
|
||||
|
||||
type eitherPointed[E, A any] struct{}
|
||||
|
||||
func (o *eitherPointed[E, A]) Of(a A) Either[E, A] {
|
||||
return Of[E, A](a)
|
||||
}
|
||||
|
||||
// Pointed implements the pointedic operations for [Either]
|
||||
func Pointed[E, A any]() pointed.Pointed[A, Either[E, A]] {
|
||||
return &eitherPointed[E, A]{}
|
||||
}
|
@@ -19,38 +19,17 @@ import (
|
||||
F "github.com/IBM/fp-go/function"
|
||||
)
|
||||
|
||||
/*
|
||||
*
|
||||
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<Either[B]>
|
||||
HKTA = HKT<A>
|
||||
HKTB = HKT<B>
|
||||
*/
|
||||
func traverse[E, A, B, HKTB, HKTRB any](
|
||||
mof func(Either[E, B]) HKTRB,
|
||||
mmap func(func(B) Either[E, B]) func(HKTB) HKTRB,
|
||||
) func(Either[E, A], func(A) HKTB) HKTRB {
|
||||
|
||||
left := F.Flow2(Left[B, E], mof)
|
||||
right := mmap(Right[E, B])
|
||||
|
||||
return func(ta Either[E, A], f func(A) HKTB) HKTRB {
|
||||
return MonadFold(ta,
|
||||
left,
|
||||
F.Flow2(f, right),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Traverse converts an [Either] of some higher kinded type into the higher kinded type of an [Either]
|
||||
func Traverse[A, E, B, HKTB, HKTRB any](
|
||||
mof func(Either[E, B]) HKTRB,
|
||||
mmap func(func(B) Either[E, B]) func(HKTB) HKTRB,
|
||||
) func(func(A) HKTB) func(Either[E, A]) HKTRB {
|
||||
delegate := traverse[E, A, B](mof, mmap)
|
||||
|
||||
left := F.Flow2(Left[B, E], mof)
|
||||
right := mmap(Right[E, B])
|
||||
|
||||
return func(f func(A) HKTB) func(Either[E, A]) HKTRB {
|
||||
return F.Bind2nd(delegate, f)
|
||||
return Fold(left, F.Flow2(f, right))
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -27,34 +27,10 @@ func Ap[A any](fa A) func(Endomorphism[A]) A {
|
||||
return G.Ap[Endomorphism[A]](fa)
|
||||
}
|
||||
|
||||
func MonadFlap[A any](fab Endomorphism[A], a A) A {
|
||||
return G.MonadFlap[Endomorphism[A]](fab, a)
|
||||
}
|
||||
|
||||
func Flap[A any](a A) func(Endomorphism[A]) A {
|
||||
return G.Flap[Endomorphism[A]](a)
|
||||
}
|
||||
|
||||
func MonadMap[A any](fa A, f Endomorphism[A]) A {
|
||||
return G.MonadMap[Endomorphism[A]](fa, f)
|
||||
}
|
||||
|
||||
func Map[A any](f Endomorphism[A]) Endomorphism[A] {
|
||||
return G.Map[Endomorphism[A]](f)
|
||||
}
|
||||
|
||||
func MonadChain[A any](ma A, f Endomorphism[A]) A {
|
||||
func MonadChain[A any](ma Endomorphism[A], f Endomorphism[A]) Endomorphism[A] {
|
||||
return G.MonadChain[Endomorphism[A]](ma, f)
|
||||
}
|
||||
|
||||
func Chain[A any](f Endomorphism[A]) Endomorphism[A] {
|
||||
return G.Chain[Endomorphism[A], A](f)
|
||||
}
|
||||
|
||||
func MonadChainFirst[A any](fa A, f Endomorphism[A]) A {
|
||||
return G.MonadChainFirst[Endomorphism[A]](fa, f)
|
||||
}
|
||||
|
||||
func ChainFirst[A any](f Endomorphism[A]) Endomorphism[A] {
|
||||
return G.ChainFirst[Endomorphism[A]](f)
|
||||
func Chain[A any](f Endomorphism[A]) Endomorphism[Endomorphism[A]] {
|
||||
return G.Chain[Endomorphism[Endomorphism[A]], Endomorphism[A], A](f)
|
||||
}
|
||||
|
@@ -16,6 +16,7 @@
|
||||
package generic
|
||||
|
||||
import (
|
||||
F "github.com/IBM/fp-go/function"
|
||||
I "github.com/IBM/fp-go/identity/generic"
|
||||
)
|
||||
|
||||
@@ -27,34 +28,10 @@ func Ap[GA ~func(A) A, A any](fa A) func(GA) A {
|
||||
return I.Ap[GA, A, A](fa)
|
||||
}
|
||||
|
||||
func MonadFlap[GA ~func(A) A, A any](fab GA, a A) A {
|
||||
return I.MonadFlap[GA, A, A](fab, a)
|
||||
func MonadChain[GA ~func(A) A, A any](ma GA, f GA) GA {
|
||||
return Compose(ma, f)
|
||||
}
|
||||
|
||||
func Flap[GA ~func(A) A, A any](a A) func(GA) A {
|
||||
return I.Flap[GA, A, A](a)
|
||||
}
|
||||
|
||||
func MonadMap[GA ~func(A) A, A any](fa A, f GA) A {
|
||||
return I.MonadMap[GA, A, A](fa, f)
|
||||
}
|
||||
|
||||
func Map[GA ~func(A) A, A any](f GA) GA {
|
||||
return I.Map[GA, A, A](f)
|
||||
}
|
||||
|
||||
func MonadChain[GA ~func(A) A, A any](ma A, f GA) A {
|
||||
return I.MonadChain[GA, A, A](ma, f)
|
||||
}
|
||||
|
||||
func Chain[GA ~func(A) A, A any](f GA) GA {
|
||||
return I.Chain[GA, A](f)
|
||||
}
|
||||
|
||||
func MonadChainFirst[GA ~func(A) A, A any](fa A, f GA) A {
|
||||
return I.MonadChainFirst[GA, A, A](fa, f)
|
||||
}
|
||||
|
||||
func ChainFirst[GA ~func(A) A, A any](f GA) GA {
|
||||
return I.ChainFirst[GA, A, A](f)
|
||||
func Chain[ENDO ~func(GA) GA, GA ~func(A) A, A any](f GA) ENDO {
|
||||
return Of[ENDO](F.Bind2nd(Compose[GA], f))
|
||||
}
|
||||
|
@@ -28,6 +28,16 @@ func Of[ENDO ~func(A) A, F ~func(A) A, A any](f F) ENDO {
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap converts any function to an [Endomorphism]
|
||||
func Wrap[ENDO ~func(A) A, F ~func(A) A, A any](f F) ENDO {
|
||||
return Of[ENDO](f)
|
||||
}
|
||||
|
||||
// Unwrap converts any [Endomorphism] to a normal function
|
||||
func Unwrap[F ~func(A) A, ENDO ~func(A) A, A any](f ENDO) F {
|
||||
return Of[F](f)
|
||||
}
|
||||
|
||||
func Identity[ENDO ~func(A) A, A any]() ENDO {
|
||||
return Of[ENDO](F.Identity[A])
|
||||
}
|
||||
|
@@ -29,6 +29,16 @@ func Of[F ~func(A) A, A any](f F) Endomorphism[A] {
|
||||
return G.Of[Endomorphism[A]](f)
|
||||
}
|
||||
|
||||
// Wrap converts any function to an [Endomorphism]
|
||||
func Wrap[F ~func(A) A, A any](f F) Endomorphism[A] {
|
||||
return G.Wrap[Endomorphism[A]](f)
|
||||
}
|
||||
|
||||
// Unwrap converts any [Endomorphism] to a function
|
||||
func Unwrap[F ~func(A) A, A any](f Endomorphism[A]) F {
|
||||
return G.Unwrap[F](f)
|
||||
}
|
||||
|
||||
// Identity returns the identity [Endomorphism]
|
||||
func Identity[A any]() Endomorphism[A] {
|
||||
return G.Identity[Endomorphism[A]]()
|
||||
|
8
eq/eq.go
8
eq/eq.go
@@ -27,20 +27,20 @@ type eq[T any] struct {
|
||||
c func(x, y T) bool
|
||||
}
|
||||
|
||||
func (self eq[T]) Equals(x, y T) bool {
|
||||
return self.c(x, y)
|
||||
func (e eq[T]) Equals(x, y T) bool {
|
||||
return e.c(x, y)
|
||||
}
|
||||
|
||||
func strictEq[A comparable](a, b A) bool {
|
||||
return a == b
|
||||
}
|
||||
|
||||
// FromStrictEquals constructs an `Eq` from the canonical comparison function
|
||||
// FromStrictEquals constructs an [EQ.Eq] from the canonical comparison function
|
||||
func FromStrictEquals[T comparable]() Eq[T] {
|
||||
return FromEquals(strictEq[T])
|
||||
}
|
||||
|
||||
// FromEquals constructs an `Eq` from the comparison function
|
||||
// FromEquals constructs an [EQ.Eq] from the comparison function
|
||||
func FromEquals[T any](c func(x, y T) bool) Eq[T] {
|
||||
return eq[T]{c: c}
|
||||
}
|
||||
|
@@ -16,18 +16,18 @@
|
||||
package exec
|
||||
|
||||
import (
|
||||
T "github.com/IBM/fp-go/tuple"
|
||||
P "github.com/IBM/fp-go/pair"
|
||||
)
|
||||
|
||||
type (
|
||||
// CommandOutput represents the output of executing a command. The first field in the [Tuple2] is
|
||||
// stdout, the second one is stderr. Use [StdOut] and [StdErr] to access these fields
|
||||
CommandOutput = T.Tuple2[[]byte, []byte]
|
||||
CommandOutput = P.Pair[[]byte, []byte]
|
||||
)
|
||||
|
||||
var (
|
||||
// StdOut returns the field of a [CommandOutput] representing `stdout`
|
||||
StdOut = T.First[[]byte, []byte]
|
||||
StdOut = P.Head[[]byte, []byte]
|
||||
// StdErr returns the field of a [CommandOutput] representing `stderr`
|
||||
StdErr = T.Second[[]byte, []byte]
|
||||
StdErr = P.Tail[[]byte, []byte]
|
||||
)
|
||||
|
@@ -32,6 +32,11 @@ func ToReader[R io.Reader](r R) io.Reader {
|
||||
return r
|
||||
}
|
||||
|
||||
// ToWriter converts a [io.Writer]
|
||||
func ToWriter[W io.Writer](w W) io.Writer {
|
||||
return w
|
||||
}
|
||||
|
||||
// ToCloser converts a [io.Closer]
|
||||
func ToCloser[C io.Closer](c C) io.Closer {
|
||||
return c
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// Code generated by go generate; DO NOT EDIT.
|
||||
// This file was generated by robots at
|
||||
// 2023-12-18 09:38:59.1616876 +0100 CET m=+0.008641801
|
||||
// 2024-02-29 16:19:01.120389 +0100 CET m=+0.011216001
|
||||
|
||||
package function
|
||||
|
||||
|
@@ -25,13 +25,13 @@ func Memoize[K comparable, T any](f func(K) T) func(K) T {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
func ContramapMemoize[T, A any, K comparable](kf func(A) K) func(func(A) T) func(A) T {
|
||||
return G.ContramapMemoize[func(A) T](kf)
|
||||
}
|
||||
|
||||
// CacheCallback converts a unary function into a unary function that caches the value depending on the parameter
|
||||
func CacheCallback[
|
||||
A any, K comparable, T any](kf func(A) K, getOrCreate func(K, func() func() T) func() T) func(func(A) T) func(A) T {
|
||||
T, A any, K comparable](kf func(A) K, getOrCreate func(K, func() func() T) func() T) func(func(A) T) func(A) T {
|
||||
return G.CacheCallback[func(func(A) T) func(A) T](kf, getOrCreate)
|
||||
}
|
||||
|
||||
|
252
function/gen.go
252
function/gen.go
@@ -1,6 +1,6 @@
|
||||
// Code generated by go generate; DO NOT EDIT.
|
||||
// This file was generated by robots at
|
||||
// 2023-12-18 09:38:51.4946446 +0100 CET m=+0.008838401
|
||||
// 2024-02-29 16:18:53.6664566 +0100 CET m=+0.011085101
|
||||
|
||||
package function
|
||||
|
||||
@@ -34,8 +34,7 @@ func Unsliced0[F ~func([]T) R, T, R any](f F) func() R {
|
||||
// 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 {
|
||||
t1 := f1(t0)
|
||||
return t1
|
||||
return f1(t0)
|
||||
}
|
||||
|
||||
// Flow1 creates a function that takes an initial value t0 and successively applies 1 functions where the input of a function is the return value of the previous function
|
||||
@@ -93,9 +92,7 @@ func Unsliced1[F ~func([]T) R, T, R any](f F) func(T) R {
|
||||
// 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 {
|
||||
t1 := f1(t0)
|
||||
t2 := f2(t1)
|
||||
return t2
|
||||
return f2(f1(t0))
|
||||
}
|
||||
|
||||
// Flow2 creates a function that takes an initial value t0 and successively applies 2 functions where the input of a function is the return value of the previous function
|
||||
@@ -155,10 +152,7 @@ func Unsliced2[F ~func([]T) R, T, R any](f F) func(T, T) R {
|
||||
// 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 {
|
||||
t1 := f1(t0)
|
||||
t2 := f2(t1)
|
||||
t3 := f3(t2)
|
||||
return t3
|
||||
return f3(f2(f1(t0)))
|
||||
}
|
||||
|
||||
// Flow3 creates a function that takes an initial value t0 and successively applies 3 functions where the input of a function is the return value of the previous function
|
||||
@@ -220,11 +214,7 @@ func Unsliced3[F ~func([]T) R, T, R any](f F) func(T, T, T) R {
|
||||
// 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 {
|
||||
t1 := f1(t0)
|
||||
t2 := f2(t1)
|
||||
t3 := f3(t2)
|
||||
t4 := f4(t3)
|
||||
return t4
|
||||
return f4(f3(f2(f1(t0))))
|
||||
}
|
||||
|
||||
// Flow4 creates a function that takes an initial value t0 and successively applies 4 functions where the input of a function is the return value of the previous function
|
||||
@@ -288,12 +278,7 @@ func Unsliced4[F ~func([]T) R, T, R any](f F) func(T, T, T, T) R {
|
||||
// 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 {
|
||||
t1 := f1(t0)
|
||||
t2 := f2(t1)
|
||||
t3 := f3(t2)
|
||||
t4 := f4(t3)
|
||||
t5 := f5(t4)
|
||||
return t5
|
||||
return f5(f4(f3(f2(f1(t0)))))
|
||||
}
|
||||
|
||||
// Flow5 creates a function that takes an initial value t0 and successively applies 5 functions where the input of a function is the return value of the previous function
|
||||
@@ -359,13 +344,7 @@ func Unsliced5[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T) R {
|
||||
// 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 {
|
||||
t1 := f1(t0)
|
||||
t2 := f2(t1)
|
||||
t3 := f3(t2)
|
||||
t4 := f4(t3)
|
||||
t5 := f5(t4)
|
||||
t6 := f6(t5)
|
||||
return t6
|
||||
return f6(f5(f4(f3(f2(f1(t0))))))
|
||||
}
|
||||
|
||||
// Flow6 creates a function that takes an initial value t0 and successively applies 6 functions where the input of a function is the return value of the previous function
|
||||
@@ -433,14 +412,7 @@ func Unsliced6[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T) R {
|
||||
// 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 {
|
||||
t1 := f1(t0)
|
||||
t2 := f2(t1)
|
||||
t3 := f3(t2)
|
||||
t4 := f4(t3)
|
||||
t5 := f5(t4)
|
||||
t6 := f6(t5)
|
||||
t7 := f7(t6)
|
||||
return t7
|
||||
return f7(f6(f5(f4(f3(f2(f1(t0)))))))
|
||||
}
|
||||
|
||||
// Flow7 creates a function that takes an initial value t0 and successively applies 7 functions where the input of a function is the return value of the previous function
|
||||
@@ -510,15 +482,7 @@ func Unsliced7[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T) R {
|
||||
// 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 {
|
||||
t1 := f1(t0)
|
||||
t2 := f2(t1)
|
||||
t3 := f3(t2)
|
||||
t4 := f4(t3)
|
||||
t5 := f5(t4)
|
||||
t6 := f6(t5)
|
||||
t7 := f7(t6)
|
||||
t8 := f8(t7)
|
||||
return t8
|
||||
return f8(f7(f6(f5(f4(f3(f2(f1(t0))))))))
|
||||
}
|
||||
|
||||
// Flow8 creates a function that takes an initial value t0 and successively applies 8 functions where the input of a function is the return value of the previous function
|
||||
@@ -590,16 +554,7 @@ func Unsliced8[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T) R {
|
||||
// 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 {
|
||||
t1 := f1(t0)
|
||||
t2 := f2(t1)
|
||||
t3 := f3(t2)
|
||||
t4 := f4(t3)
|
||||
t5 := f5(t4)
|
||||
t6 := f6(t5)
|
||||
t7 := f7(t6)
|
||||
t8 := f8(t7)
|
||||
t9 := f9(t8)
|
||||
return t9
|
||||
return f9(f8(f7(f6(f5(f4(f3(f2(f1(t0)))))))))
|
||||
}
|
||||
|
||||
// Flow9 creates a function that takes an initial value t0 and successively applies 9 functions where the input of a function is the return value of the previous function
|
||||
@@ -673,17 +628,7 @@ func Unsliced9[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T) R
|
||||
// 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 {
|
||||
t1 := f1(t0)
|
||||
t2 := f2(t1)
|
||||
t3 := f3(t2)
|
||||
t4 := f4(t3)
|
||||
t5 := f5(t4)
|
||||
t6 := f6(t5)
|
||||
t7 := f7(t6)
|
||||
t8 := f8(t7)
|
||||
t9 := f9(t8)
|
||||
t10 := f10(t9)
|
||||
return t10
|
||||
return f10(f9(f8(f7(f6(f5(f4(f3(f2(f1(t0))))))))))
|
||||
}
|
||||
|
||||
// Flow10 creates a function that takes an initial value t0 and successively applies 10 functions where the input of a function is the return value of the previous function
|
||||
@@ -759,18 +704,7 @@ func Unsliced10[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T, T
|
||||
// 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 {
|
||||
t1 := f1(t0)
|
||||
t2 := f2(t1)
|
||||
t3 := f3(t2)
|
||||
t4 := f4(t3)
|
||||
t5 := f5(t4)
|
||||
t6 := f6(t5)
|
||||
t7 := f7(t6)
|
||||
t8 := f8(t7)
|
||||
t9 := f9(t8)
|
||||
t10 := f10(t9)
|
||||
t11 := f11(t10)
|
||||
return t11
|
||||
return f11(f10(f9(f8(f7(f6(f5(f4(f3(f2(f1(t0)))))))))))
|
||||
}
|
||||
|
||||
// Flow11 creates a function that takes an initial value t0 and successively applies 11 functions where the input of a function is the return value of the previous function
|
||||
@@ -848,19 +782,7 @@ func Unsliced11[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T, T
|
||||
// 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 {
|
||||
t1 := f1(t0)
|
||||
t2 := f2(t1)
|
||||
t3 := f3(t2)
|
||||
t4 := f4(t3)
|
||||
t5 := f5(t4)
|
||||
t6 := f6(t5)
|
||||
t7 := f7(t6)
|
||||
t8 := f8(t7)
|
||||
t9 := f9(t8)
|
||||
t10 := f10(t9)
|
||||
t11 := f11(t10)
|
||||
t12 := f12(t11)
|
||||
return t12
|
||||
return f12(f11(f10(f9(f8(f7(f6(f5(f4(f3(f2(f1(t0))))))))))))
|
||||
}
|
||||
|
||||
// Flow12 creates a function that takes an initial value t0 and successively applies 12 functions where the input of a function is the return value of the previous function
|
||||
@@ -940,20 +862,7 @@ func Unsliced12[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T, T
|
||||
// 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 {
|
||||
t1 := f1(t0)
|
||||
t2 := f2(t1)
|
||||
t3 := f3(t2)
|
||||
t4 := f4(t3)
|
||||
t5 := f5(t4)
|
||||
t6 := f6(t5)
|
||||
t7 := f7(t6)
|
||||
t8 := f8(t7)
|
||||
t9 := f9(t8)
|
||||
t10 := f10(t9)
|
||||
t11 := f11(t10)
|
||||
t12 := f12(t11)
|
||||
t13 := f13(t12)
|
||||
return t13
|
||||
return f13(f12(f11(f10(f9(f8(f7(f6(f5(f4(f3(f2(f1(t0)))))))))))))
|
||||
}
|
||||
|
||||
// Flow13 creates a function that takes an initial value t0 and successively applies 13 functions where the input of a function is the return value of the previous function
|
||||
@@ -1035,21 +944,7 @@ func Unsliced13[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T, T
|
||||
// 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 {
|
||||
t1 := f1(t0)
|
||||
t2 := f2(t1)
|
||||
t3 := f3(t2)
|
||||
t4 := f4(t3)
|
||||
t5 := f5(t4)
|
||||
t6 := f6(t5)
|
||||
t7 := f7(t6)
|
||||
t8 := f8(t7)
|
||||
t9 := f9(t8)
|
||||
t10 := f10(t9)
|
||||
t11 := f11(t10)
|
||||
t12 := f12(t11)
|
||||
t13 := f13(t12)
|
||||
t14 := f14(t13)
|
||||
return t14
|
||||
return f14(f13(f12(f11(f10(f9(f8(f7(f6(f5(f4(f3(f2(f1(t0))))))))))))))
|
||||
}
|
||||
|
||||
// Flow14 creates a function that takes an initial value t0 and successively applies 14 functions where the input of a function is the return value of the previous function
|
||||
@@ -1133,22 +1028,7 @@ func Unsliced14[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T, T
|
||||
// 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 {
|
||||
t1 := f1(t0)
|
||||
t2 := f2(t1)
|
||||
t3 := f3(t2)
|
||||
t4 := f4(t3)
|
||||
t5 := f5(t4)
|
||||
t6 := f6(t5)
|
||||
t7 := f7(t6)
|
||||
t8 := f8(t7)
|
||||
t9 := f9(t8)
|
||||
t10 := f10(t9)
|
||||
t11 := f11(t10)
|
||||
t12 := f12(t11)
|
||||
t13 := f13(t12)
|
||||
t14 := f14(t13)
|
||||
t15 := f15(t14)
|
||||
return t15
|
||||
return f15(f14(f13(f12(f11(f10(f9(f8(f7(f6(f5(f4(f3(f2(f1(t0)))))))))))))))
|
||||
}
|
||||
|
||||
// Flow15 creates a function that takes an initial value t0 and successively applies 15 functions where the input of a function is the return value of the previous function
|
||||
@@ -1234,23 +1114,7 @@ func Unsliced15[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T, T
|
||||
// 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 {
|
||||
t1 := f1(t0)
|
||||
t2 := f2(t1)
|
||||
t3 := f3(t2)
|
||||
t4 := f4(t3)
|
||||
t5 := f5(t4)
|
||||
t6 := f6(t5)
|
||||
t7 := f7(t6)
|
||||
t8 := f8(t7)
|
||||
t9 := f9(t8)
|
||||
t10 := f10(t9)
|
||||
t11 := f11(t10)
|
||||
t12 := f12(t11)
|
||||
t13 := f13(t12)
|
||||
t14 := f14(t13)
|
||||
t15 := f15(t14)
|
||||
t16 := f16(t15)
|
||||
return t16
|
||||
return f16(f15(f14(f13(f12(f11(f10(f9(f8(f7(f6(f5(f4(f3(f2(f1(t0))))))))))))))))
|
||||
}
|
||||
|
||||
// Flow16 creates a function that takes an initial value t0 and successively applies 16 functions where the input of a function is the return value of the previous function
|
||||
@@ -1338,24 +1202,7 @@ func Unsliced16[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T, T
|
||||
// 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 {
|
||||
t1 := f1(t0)
|
||||
t2 := f2(t1)
|
||||
t3 := f3(t2)
|
||||
t4 := f4(t3)
|
||||
t5 := f5(t4)
|
||||
t6 := f6(t5)
|
||||
t7 := f7(t6)
|
||||
t8 := f8(t7)
|
||||
t9 := f9(t8)
|
||||
t10 := f10(t9)
|
||||
t11 := f11(t10)
|
||||
t12 := f12(t11)
|
||||
t13 := f13(t12)
|
||||
t14 := f14(t13)
|
||||
t15 := f15(t14)
|
||||
t16 := f16(t15)
|
||||
t17 := f17(t16)
|
||||
return t17
|
||||
return f17(f16(f15(f14(f13(f12(f11(f10(f9(f8(f7(f6(f5(f4(f3(f2(f1(t0)))))))))))))))))
|
||||
}
|
||||
|
||||
// Flow17 creates a function that takes an initial value t0 and successively applies 17 functions where the input of a function is the return value of the previous function
|
||||
@@ -1445,25 +1292,7 @@ func Unsliced17[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T, T
|
||||
// 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 {
|
||||
t1 := f1(t0)
|
||||
t2 := f2(t1)
|
||||
t3 := f3(t2)
|
||||
t4 := f4(t3)
|
||||
t5 := f5(t4)
|
||||
t6 := f6(t5)
|
||||
t7 := f7(t6)
|
||||
t8 := f8(t7)
|
||||
t9 := f9(t8)
|
||||
t10 := f10(t9)
|
||||
t11 := f11(t10)
|
||||
t12 := f12(t11)
|
||||
t13 := f13(t12)
|
||||
t14 := f14(t13)
|
||||
t15 := f15(t14)
|
||||
t16 := f16(t15)
|
||||
t17 := f17(t16)
|
||||
t18 := f18(t17)
|
||||
return t18
|
||||
return f18(f17(f16(f15(f14(f13(f12(f11(f10(f9(f8(f7(f6(f5(f4(f3(f2(f1(t0))))))))))))))))))
|
||||
}
|
||||
|
||||
// Flow18 creates a function that takes an initial value t0 and successively applies 18 functions where the input of a function is the return value of the previous function
|
||||
@@ -1555,26 +1384,7 @@ func Unsliced18[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T, T
|
||||
// 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 {
|
||||
t1 := f1(t0)
|
||||
t2 := f2(t1)
|
||||
t3 := f3(t2)
|
||||
t4 := f4(t3)
|
||||
t5 := f5(t4)
|
||||
t6 := f6(t5)
|
||||
t7 := f7(t6)
|
||||
t8 := f8(t7)
|
||||
t9 := f9(t8)
|
||||
t10 := f10(t9)
|
||||
t11 := f11(t10)
|
||||
t12 := f12(t11)
|
||||
t13 := f13(t12)
|
||||
t14 := f14(t13)
|
||||
t15 := f15(t14)
|
||||
t16 := f16(t15)
|
||||
t17 := f17(t16)
|
||||
t18 := f18(t17)
|
||||
t19 := f19(t18)
|
||||
return t19
|
||||
return f19(f18(f17(f16(f15(f14(f13(f12(f11(f10(f9(f8(f7(f6(f5(f4(f3(f2(f1(t0)))))))))))))))))))
|
||||
}
|
||||
|
||||
// Flow19 creates a function that takes an initial value t0 and successively applies 19 functions where the input of a function is the return value of the previous function
|
||||
@@ -1668,27 +1478,7 @@ func Unsliced19[F ~func([]T) R, T, R any](f F) func(T, T, T, T, T, T, T, T, T, T
|
||||
// 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 {
|
||||
t1 := f1(t0)
|
||||
t2 := f2(t1)
|
||||
t3 := f3(t2)
|
||||
t4 := f4(t3)
|
||||
t5 := f5(t4)
|
||||
t6 := f6(t5)
|
||||
t7 := f7(t6)
|
||||
t8 := f8(t7)
|
||||
t9 := f9(t8)
|
||||
t10 := f10(t9)
|
||||
t11 := f11(t10)
|
||||
t12 := f12(t11)
|
||||
t13 := f13(t12)
|
||||
t14 := f14(t13)
|
||||
t15 := f15(t14)
|
||||
t16 := f16(t15)
|
||||
t17 := f17(t16)
|
||||
t18 := f18(t17)
|
||||
t19 := f19(t18)
|
||||
t20 := f20(t19)
|
||||
return t20
|
||||
return f20(f19(f18(f17(f16(f15(f14(f13(f12(f11(f10(f9(f8(f7(f6(f5(f4(f3(f2(f1(t0))))))))))))))))))))
|
||||
}
|
||||
|
||||
// Flow20 creates a function that takes an initial value t0 and successively applies 20 functions where the input of a function is the return value of the previous function
|
||||
|
8
go.mod
8
go.mod
@@ -3,15 +3,15 @@ module github.com/IBM/fp-go
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/urfave/cli/v2 v2.26.0
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/urfave/cli/v2 v2.27.7
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
32
go.sum
32
go.sum
@@ -1,21 +1,29 @@
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=
|
||||
github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
|
||||
github.com/urfave/cli/v2 v2.26.0 h1:3f3AMg3HpThFNT4I++TKOejZO8yU55t3JnnSr4S4QEI=
|
||||
github.com/urfave/cli/v2 v2.26.0/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||
github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e h1:+SOyEddqYF09QP7vr7CgJ1eti3pY9Fn3LHO1M1r/0sI=
|
||||
github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/urfave/cli/v2 v2.27.4 h1:o1owoI+02Eb+K107p27wEX9Bb8eqIoZCfLXloLUSWJ8=
|
||||
github.com/urfave/cli/v2 v2.27.4/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ=
|
||||
github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
|
||||
github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
|
||||
github.com/urfave/cli/v2 v2.27.6 h1:VdRdS98FNhKZ8/Az8B7MTyGQmpIr36O1EHybx/LaZ4g=
|
||||
github.com/urfave/cli/v2 v2.27.6/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
|
||||
github.com/urfave/cli/v2 v2.27.7 h1:bH59vdhbjLv3LAvIu6gd0usJHgoTTPhCFib8qqOwXYU=
|
||||
github.com/urfave/cli/v2 v2.27.7/go.mod h1:CyNAG/xg+iAOg0N4MPGZqVmv2rCoP267496AOXUZjA4=
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
387
http/builder/builder.go
Normal file
387
http/builder/builder.go
Normal file
@@ -0,0 +1,387 @@
|
||||
// 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 builder
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
A "github.com/IBM/fp-go/array"
|
||||
B "github.com/IBM/fp-go/bytes"
|
||||
E "github.com/IBM/fp-go/either"
|
||||
ENDO "github.com/IBM/fp-go/endomorphism"
|
||||
F "github.com/IBM/fp-go/function"
|
||||
C "github.com/IBM/fp-go/http/content"
|
||||
FM "github.com/IBM/fp-go/http/form"
|
||||
H "github.com/IBM/fp-go/http/headers"
|
||||
J "github.com/IBM/fp-go/json"
|
||||
LZ "github.com/IBM/fp-go/lazy"
|
||||
L "github.com/IBM/fp-go/optics/lens"
|
||||
O "github.com/IBM/fp-go/option"
|
||||
R "github.com/IBM/fp-go/record"
|
||||
S "github.com/IBM/fp-go/string"
|
||||
T "github.com/IBM/fp-go/tuple"
|
||||
)
|
||||
|
||||
type (
|
||||
Builder struct {
|
||||
method O.Option[string]
|
||||
url string
|
||||
headers http.Header
|
||||
body O.Option[E.Either[error, []byte]]
|
||||
query url.Values
|
||||
}
|
||||
|
||||
// Endomorphism returns an [ENDO.Endomorphism] that transforms a builder
|
||||
Endomorphism = ENDO.Endomorphism[*Builder]
|
||||
)
|
||||
|
||||
var (
|
||||
// Default is the default builder
|
||||
Default = &Builder{method: O.Some(defaultMethod()), headers: make(http.Header), body: noBody}
|
||||
|
||||
defaultMethod = F.Constant(http.MethodGet)
|
||||
|
||||
// Monoid is the [M.Monoid] for the [Endomorphism]
|
||||
Monoid = ENDO.Monoid[*Builder]()
|
||||
|
||||
// Url is a [L.Lens] for the URL
|
||||
//
|
||||
// Deprecated: use [URL] instead
|
||||
Url = L.MakeLensRef((*Builder).GetURL, (*Builder).SetURL)
|
||||
// URL is a [L.Lens] for the URL
|
||||
URL = L.MakeLensRef((*Builder).GetURL, (*Builder).SetURL)
|
||||
// Method is a [L.Lens] for the HTTP method
|
||||
Method = L.MakeLensRef((*Builder).GetMethod, (*Builder).SetMethod)
|
||||
// Body is a [L.Lens] for the request body
|
||||
Body = L.MakeLensRef((*Builder).GetBody, (*Builder).SetBody)
|
||||
// Headers is a [L.Lens] for the complete set of request headers
|
||||
Headers = L.MakeLensRef((*Builder).GetHeaders, (*Builder).SetHeaders)
|
||||
// Query is a [L.Lens] for the set of query parameters
|
||||
Query = L.MakeLensRef((*Builder).GetQuery, (*Builder).SetQuery)
|
||||
|
||||
rawQuery = L.MakeLensRef(getRawQuery, setRawQuery)
|
||||
|
||||
getHeader = F.Bind2of2((*Builder).GetHeader)
|
||||
delHeader = F.Bind2of2((*Builder).DelHeader)
|
||||
setHeader = F.Bind2of3((*Builder).SetHeader)
|
||||
|
||||
noHeader = O.None[string]()
|
||||
noBody = O.None[E.Either[error, []byte]]()
|
||||
noQueryArg = O.None[string]()
|
||||
|
||||
parseURL = E.Eitherize1(url.Parse)
|
||||
parseQuery = E.Eitherize1(url.ParseQuery)
|
||||
|
||||
// WithQuery creates a [Endomorphism] for a complete set of query parameters
|
||||
WithQuery = Query.Set
|
||||
// WithMethod creates a [Endomorphism] for a certain method
|
||||
WithMethod = Method.Set
|
||||
// WithUrl creates a [Endomorphism] for the URL
|
||||
//
|
||||
// Deprecated: use [WithURL] instead
|
||||
WithUrl = URL.Set
|
||||
// WithURL creates a [Endomorphism] for the URL
|
||||
WithURL = URL.Set
|
||||
// WithHeaders creates a [Endomorphism] for a set of headers
|
||||
WithHeaders = Headers.Set
|
||||
// WithBody creates a [Endomorphism] for a request body
|
||||
WithBody = F.Flow2(
|
||||
O.Of[E.Either[error, []byte]],
|
||||
Body.Set,
|
||||
)
|
||||
// WithBytes creates a [Endomorphism] for a request body using bytes
|
||||
WithBytes = F.Flow2(
|
||||
E.Of[error, []byte],
|
||||
WithBody,
|
||||
)
|
||||
// WithContentType adds the [H.ContentType] header
|
||||
WithContentType = WithHeader(H.ContentType)
|
||||
// WithAuthorization adds the [H.Authorization] header
|
||||
WithAuthorization = WithHeader(H.Authorization)
|
||||
|
||||
// WithGet adds the [http.MethodGet] method
|
||||
WithGet = WithMethod(http.MethodGet)
|
||||
// WithPost adds the [http.MethodPost] method
|
||||
WithPost = WithMethod(http.MethodPost)
|
||||
// WithPut adds the [http.MethodPut] method
|
||||
WithPut = WithMethod(http.MethodPut)
|
||||
// WithDelete adds the [http.MethodDelete] method
|
||||
WithDelete = WithMethod(http.MethodDelete)
|
||||
|
||||
// WithBearer creates a [Endomorphism] to add a Bearer [H.Authorization] header
|
||||
WithBearer = F.Flow2(
|
||||
S.Format[string]("Bearer %s"),
|
||||
WithAuthorization,
|
||||
)
|
||||
|
||||
// WithoutBody creates a [Endomorphism] to remove the body
|
||||
WithoutBody = F.Pipe1(
|
||||
noBody,
|
||||
Body.Set,
|
||||
)
|
||||
|
||||
// WithFormData creates a [Endomorphism] to send form data payload
|
||||
WithFormData = F.Flow4(
|
||||
url.Values.Encode,
|
||||
S.ToBytes,
|
||||
WithBytes,
|
||||
ENDO.Chain(WithContentType(C.FormEncoded)),
|
||||
)
|
||||
|
||||
// bodyAsBytes returns a []byte with a fallback to the empty array
|
||||
bodyAsBytes = O.Fold(B.Empty, E.Fold(F.Ignore1of1[error](B.Empty), F.Identity[[]byte]))
|
||||
)
|
||||
|
||||
func setRawQuery(u *url.URL, raw string) *url.URL {
|
||||
u.RawQuery = raw
|
||||
return u
|
||||
}
|
||||
|
||||
func getRawQuery(u *url.URL) string {
|
||||
return u.RawQuery
|
||||
}
|
||||
|
||||
func (builder *Builder) clone() *Builder {
|
||||
cpy := *builder
|
||||
cpy.headers = cpy.headers.Clone()
|
||||
return &cpy
|
||||
}
|
||||
|
||||
// GetTargetUrl constructs a full URL with query parameters on top of the provided URL string
|
||||
//
|
||||
// Deprecated: use [GetTargetURL] instead
|
||||
func (builder *Builder) GetTargetUrl() E.Either[error, string] {
|
||||
return builder.GetTargetURL()
|
||||
}
|
||||
|
||||
// GetTargetURL constructs a full URL with query parameters on top of the provided URL string
|
||||
func (builder *Builder) GetTargetURL() E.Either[error, string] {
|
||||
// construct the final URL
|
||||
return F.Pipe3(
|
||||
builder,
|
||||
Url.Get,
|
||||
parseURL,
|
||||
E.Chain(F.Flow4(
|
||||
T.Replicate2[*url.URL],
|
||||
T.Map2(
|
||||
F.Flow2(
|
||||
F.Curry2(setRawQuery),
|
||||
E.Of[error, func(string) *url.URL],
|
||||
),
|
||||
F.Flow3(
|
||||
rawQuery.Get,
|
||||
parseQuery,
|
||||
E.Map[error](F.Flow2(
|
||||
F.Curry2(FM.ValuesMonoid.Concat)(builder.GetQuery()),
|
||||
(url.Values).Encode,
|
||||
)),
|
||||
),
|
||||
),
|
||||
T.Tupled2(E.MonadAp[*url.URL, error, string]),
|
||||
E.Map[error]((*url.URL).String),
|
||||
)),
|
||||
)
|
||||
}
|
||||
|
||||
// Deprecated: use [GetURL] instead
|
||||
func (builder *Builder) GetUrl() string {
|
||||
return builder.url
|
||||
}
|
||||
|
||||
func (builder *Builder) GetURL() string {
|
||||
return builder.url
|
||||
}
|
||||
|
||||
func (builder *Builder) GetMethod() string {
|
||||
return F.Pipe1(
|
||||
builder.method,
|
||||
O.GetOrElse(defaultMethod),
|
||||
)
|
||||
}
|
||||
|
||||
func (builder *Builder) GetHeaders() http.Header {
|
||||
return builder.headers
|
||||
}
|
||||
|
||||
func (builder *Builder) GetQuery() url.Values {
|
||||
return builder.query
|
||||
}
|
||||
|
||||
func (builder *Builder) SetQuery(query url.Values) *Builder {
|
||||
builder.query = query
|
||||
return builder
|
||||
}
|
||||
|
||||
func (builder *Builder) GetBody() O.Option[E.Either[error, []byte]] {
|
||||
return builder.body
|
||||
}
|
||||
|
||||
func (builder *Builder) SetMethod(method string) *Builder {
|
||||
builder.method = O.Some(method)
|
||||
return builder
|
||||
}
|
||||
|
||||
// Deprecated: use [SetURL] instead
|
||||
func (builder *Builder) SetUrl(url string) *Builder {
|
||||
builder.url = url
|
||||
return builder
|
||||
}
|
||||
|
||||
func (builder *Builder) SetURL(url string) *Builder {
|
||||
builder.url = url
|
||||
return builder
|
||||
}
|
||||
|
||||
func (builder *Builder) SetHeaders(headers http.Header) *Builder {
|
||||
builder.headers = headers
|
||||
return builder
|
||||
}
|
||||
|
||||
func (builder *Builder) SetBody(body O.Option[E.Either[error, []byte]]) *Builder {
|
||||
builder.body = body
|
||||
return builder
|
||||
}
|
||||
|
||||
func (builder *Builder) SetHeader(name, value string) *Builder {
|
||||
builder.headers.Set(name, value)
|
||||
return builder
|
||||
}
|
||||
|
||||
func (builder *Builder) DelHeader(name string) *Builder {
|
||||
builder.headers.Del(name)
|
||||
return builder
|
||||
}
|
||||
|
||||
func (builder *Builder) GetHeader(name string) O.Option[string] {
|
||||
return F.Pipe2(
|
||||
name,
|
||||
builder.headers.Get,
|
||||
O.FromPredicate(S.IsNonEmpty),
|
||||
)
|
||||
}
|
||||
|
||||
func (builder *Builder) GetHeaderValues(name string) []string {
|
||||
return builder.headers.Values(name)
|
||||
}
|
||||
|
||||
// GetHash returns a hash value for the builder that can be used as a cache key
|
||||
func (builder *Builder) GetHash() string {
|
||||
return MakeHash(builder)
|
||||
}
|
||||
|
||||
// Header returns a [L.Lens] for a single header
|
||||
func Header(name string) L.Lens[*Builder, O.Option[string]] {
|
||||
get := getHeader(name)
|
||||
set := F.Bind1of2(setHeader(name))
|
||||
del := F.Flow2(
|
||||
LZ.Of[*Builder],
|
||||
LZ.Map(delHeader(name)),
|
||||
)
|
||||
|
||||
return L.MakeLens(get, func(b *Builder, value O.Option[string]) *Builder {
|
||||
cpy := b.clone()
|
||||
return F.Pipe1(
|
||||
value,
|
||||
O.Fold(del(cpy), set(cpy)),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
// WithHeader creates a [Endomorphism] for a certain header
|
||||
func WithHeader(name string) func(value string) Endomorphism {
|
||||
return F.Flow2(
|
||||
O.Of[string],
|
||||
Header(name).Set,
|
||||
)
|
||||
}
|
||||
|
||||
// WithoutHeader creates a [Endomorphism] to remove a certain header
|
||||
func WithoutHeader(name string) Endomorphism {
|
||||
return Header(name).Set(noHeader)
|
||||
}
|
||||
|
||||
// WithJson creates a [Endomorphism] to send JSON payload
|
||||
//
|
||||
// Deprecated: use [WithJSON] instead
|
||||
func WithJson[T any](data T) Endomorphism {
|
||||
return WithJSON[T](data)
|
||||
}
|
||||
|
||||
// WithJSON creates a [Endomorphism] to send JSON payload
|
||||
func WithJSON[T any](data T) Endomorphism {
|
||||
return Monoid.Concat(
|
||||
F.Pipe2(
|
||||
data,
|
||||
J.Marshal[T],
|
||||
WithBody,
|
||||
),
|
||||
WithContentType(C.JSON),
|
||||
)
|
||||
}
|
||||
|
||||
// QueryArg is a [L.Lens] for the first value of a query argument
|
||||
func QueryArg(name string) L.Lens[*Builder, O.Option[string]] {
|
||||
return F.Pipe1(
|
||||
Query,
|
||||
L.Compose[*Builder](FM.AtValue(name)),
|
||||
)
|
||||
}
|
||||
|
||||
// WithQueryArg creates a [Endomorphism] for a certain query argument
|
||||
func WithQueryArg(name string) func(value string) Endomorphism {
|
||||
return F.Flow2(
|
||||
O.Of[string],
|
||||
QueryArg(name).Set,
|
||||
)
|
||||
}
|
||||
|
||||
// WithoutQueryArg creates a [Endomorphism] that removes a query argument
|
||||
func WithoutQueryArg(name string) Endomorphism {
|
||||
return QueryArg(name).Set(noQueryArg)
|
||||
}
|
||||
|
||||
func hashWriteValue(buf *bytes.Buffer, value string) *bytes.Buffer {
|
||||
buf.WriteString(value)
|
||||
return buf
|
||||
}
|
||||
|
||||
func hashWriteQuery(name string, buf *bytes.Buffer, values []string) *bytes.Buffer {
|
||||
buf.WriteString(name)
|
||||
return A.Reduce(hashWriteValue, buf)(values)
|
||||
}
|
||||
|
||||
func makeBytes(b *Builder) []byte {
|
||||
var buf bytes.Buffer
|
||||
|
||||
buf.WriteString(b.GetMethod())
|
||||
buf.WriteString(b.GetURL())
|
||||
b.GetHeaders().Write(&buf) // #nosec: G104
|
||||
|
||||
R.ReduceOrdWithIndex[[]string, *bytes.Buffer](S.Ord)(hashWriteQuery, &buf)(b.GetQuery())
|
||||
|
||||
buf.Write(bodyAsBytes(b.GetBody()))
|
||||
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
// MakeHash converts a [Builder] into a hash string, convenient to use as a cache key
|
||||
func MakeHash(b *Builder) string {
|
||||
return fmt.Sprintf("%x", sha256.Sum256(makeBytes(b)))
|
||||
}
|
93
http/builder/builder_test.go
Normal file
93
http/builder/builder_test.go
Normal file
@@ -0,0 +1,93 @@
|
||||
// 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 builder
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
F "github.com/IBM/fp-go/function"
|
||||
C "github.com/IBM/fp-go/http/content"
|
||||
FD "github.com/IBM/fp-go/http/form"
|
||||
H "github.com/IBM/fp-go/http/headers"
|
||||
O "github.com/IBM/fp-go/option"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestBuilder(t *testing.T) {
|
||||
|
||||
name := H.ContentType
|
||||
withContentType := WithHeader(name)
|
||||
withoutContentType := WithoutHeader(name)
|
||||
|
||||
b1 := F.Pipe1(
|
||||
Default,
|
||||
withContentType(C.JSON),
|
||||
)
|
||||
|
||||
b2 := F.Pipe1(
|
||||
b1,
|
||||
withContentType(C.TextPlain),
|
||||
)
|
||||
|
||||
b3 := F.Pipe1(
|
||||
b2,
|
||||
withoutContentType,
|
||||
)
|
||||
|
||||
assert.Equal(t, O.None[string](), Default.GetHeader(name))
|
||||
assert.Equal(t, O.Of(C.JSON), b1.GetHeader(name))
|
||||
assert.Equal(t, O.Of(C.TextPlain), b2.GetHeader(name))
|
||||
assert.Equal(t, O.None[string](), b3.GetHeader(name))
|
||||
}
|
||||
|
||||
func TestWithFormData(t *testing.T) {
|
||||
data := F.Pipe1(
|
||||
FD.Default,
|
||||
FD.WithValue("a")("b"),
|
||||
)
|
||||
|
||||
res := F.Pipe1(
|
||||
Default,
|
||||
WithFormData(data),
|
||||
)
|
||||
|
||||
assert.Equal(t, C.FormEncoded, Headers.Get(res).Get(H.ContentType))
|
||||
}
|
||||
|
||||
func TestHash(t *testing.T) {
|
||||
|
||||
b1 := F.Pipe4(
|
||||
Default,
|
||||
WithContentType(C.JSON),
|
||||
WithHeader(H.Accept)(C.JSON),
|
||||
WithURL("http://www.example.com"),
|
||||
WithJSON(map[string]string{"a": "b"}),
|
||||
)
|
||||
|
||||
b2 := F.Pipe4(
|
||||
Default,
|
||||
WithURL("http://www.example.com"),
|
||||
WithHeader(H.Accept)(C.JSON),
|
||||
WithContentType(C.JSON),
|
||||
WithJSON(map[string]string{"a": "b"}),
|
||||
)
|
||||
|
||||
assert.Equal(t, MakeHash(b1), MakeHash(b2))
|
||||
assert.NotEqual(t, MakeHash(Default), MakeHash(b2))
|
||||
|
||||
fmt.Println(MakeHash(b1))
|
||||
}
|
@@ -17,6 +17,7 @@ package content
|
||||
|
||||
const (
|
||||
TextPlain = "text/plain"
|
||||
Json = "application/json"
|
||||
JSON = "application/json"
|
||||
Json = JSON // Deprecated: use [JSON] instead
|
||||
FormEncoded = "application/x-www-form-urlencoded"
|
||||
)
|
||||
|
@@ -25,6 +25,7 @@ import (
|
||||
LA "github.com/IBM/fp-go/optics/lens/array"
|
||||
LRG "github.com/IBM/fp-go/optics/lens/record/generic"
|
||||
O "github.com/IBM/fp-go/option"
|
||||
RG "github.com/IBM/fp-go/record/generic"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -38,9 +39,12 @@ var (
|
||||
|
||||
noField = O.None[string]()
|
||||
|
||||
// FormMonoid is the [M.Monoid] for the [Endomorphism]
|
||||
// Monoid is the [M.Monoid] for the [Endomorphism]
|
||||
Monoid = ENDO.Monoid[url.Values]()
|
||||
|
||||
// ValuesMonoid is a [M.Monoid] to concatenate [url.Values] maps
|
||||
ValuesMonoid = RG.UnionMonoid[url.Values](A.Semigroup[string]())
|
||||
|
||||
// AtValues is a [L.Lens] that focusses on the values of a form field
|
||||
AtValues = LRG.AtRecord[url.Values, []string]
|
||||
|
||||
|
@@ -15,6 +15,18 @@
|
||||
|
||||
package headers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/textproto"
|
||||
|
||||
A "github.com/IBM/fp-go/array"
|
||||
F "github.com/IBM/fp-go/function"
|
||||
L "github.com/IBM/fp-go/optics/lens"
|
||||
LA "github.com/IBM/fp-go/optics/lens/array"
|
||||
LRG "github.com/IBM/fp-go/optics/lens/record/generic"
|
||||
RG "github.com/IBM/fp-go/record/generic"
|
||||
)
|
||||
|
||||
// HTTP headers
|
||||
const (
|
||||
Accept = "Accept"
|
||||
@@ -22,3 +34,25 @@ const (
|
||||
ContentType = "Content-Type"
|
||||
ContentLength = "Content-Length"
|
||||
)
|
||||
|
||||
var (
|
||||
// Monoid is a [M.Monoid] to concatenate [http.Header] maps
|
||||
Monoid = RG.UnionMonoid[http.Header](A.Semigroup[string]())
|
||||
|
||||
// AtValues is a [L.Lens] that focusses on the values of a header
|
||||
AtValues = F.Flow2(
|
||||
textproto.CanonicalMIMEHeaderKey,
|
||||
LRG.AtRecord[http.Header, []string],
|
||||
)
|
||||
|
||||
composeHead = F.Pipe1(
|
||||
LA.AtHead[string](),
|
||||
L.ComposeOptions[http.Header, string](A.Empty[string]()),
|
||||
)
|
||||
|
||||
// AtValue is a [L.Lens] that focusses on first value of a header
|
||||
AtValue = F.Flow2(
|
||||
AtValues,
|
||||
composeHead,
|
||||
)
|
||||
)
|
||||
|
58
http/headers/headers_test.go
Normal file
58
http/headers/headers_test.go
Normal 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 headers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
A "github.com/IBM/fp-go/array"
|
||||
"github.com/IBM/fp-go/eq"
|
||||
LT "github.com/IBM/fp-go/optics/lens/testing"
|
||||
O "github.com/IBM/fp-go/option"
|
||||
RG "github.com/IBM/fp-go/record/generic"
|
||||
S "github.com/IBM/fp-go/string"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var (
|
||||
sEq = eq.FromEquals(S.Eq)
|
||||
valuesEq = RG.Eq[http.Header](A.Eq(sEq))
|
||||
)
|
||||
|
||||
func TestLaws(t *testing.T) {
|
||||
name := "Content-Type"
|
||||
fieldLaws := LT.AssertLaws[http.Header, O.Option[string]](t, O.Eq(sEq), valuesEq)(AtValue(name))
|
||||
|
||||
n := O.None[string]()
|
||||
s1 := O.Some("s1")
|
||||
|
||||
def := make(http.Header)
|
||||
|
||||
v1 := make(http.Header)
|
||||
v1.Set(name, "v1")
|
||||
|
||||
v2 := make(http.Header)
|
||||
v2.Set("Other-Header", "v2")
|
||||
|
||||
assert.True(t, fieldLaws(def, n))
|
||||
assert.True(t, fieldLaws(v1, n))
|
||||
assert.True(t, fieldLaws(v2, n))
|
||||
|
||||
assert.True(t, fieldLaws(def, s1))
|
||||
assert.True(t, fieldLaws(v1, s1))
|
||||
assert.True(t, fieldLaws(v2, s1))
|
||||
}
|
@@ -18,15 +18,15 @@ package http
|
||||
import (
|
||||
H "net/http"
|
||||
|
||||
T "github.com/IBM/fp-go/tuple"
|
||||
P "github.com/IBM/fp-go/pair"
|
||||
)
|
||||
|
||||
type (
|
||||
// FullResponse represents a full http response, including headers and body
|
||||
FullResponse = T.Tuple2[*H.Response, []byte]
|
||||
FullResponse = P.Pair[*H.Response, []byte]
|
||||
)
|
||||
|
||||
var (
|
||||
Response = T.First[*H.Response, []byte]
|
||||
Body = T.Second[*H.Response, []byte]
|
||||
Response = P.Head[*H.Response, []byte]
|
||||
Body = P.Tail[*H.Response, []byte]
|
||||
)
|
||||
|
@@ -20,6 +20,7 @@ import (
|
||||
"io"
|
||||
"mime"
|
||||
H "net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
|
||||
A "github.com/IBM/fp-go/array"
|
||||
@@ -27,39 +28,48 @@ import (
|
||||
"github.com/IBM/fp-go/errors"
|
||||
F "github.com/IBM/fp-go/function"
|
||||
O "github.com/IBM/fp-go/option"
|
||||
P "github.com/IBM/fp-go/pair"
|
||||
R "github.com/IBM/fp-go/record/generic"
|
||||
T "github.com/IBM/fp-go/tuple"
|
||||
)
|
||||
|
||||
type (
|
||||
ParsedMediaType = T.Tuple2[string, map[string]string]
|
||||
ParsedMediaType = P.Pair[string, map[string]string]
|
||||
|
||||
HttpError struct {
|
||||
statusCode int
|
||||
headers H.Header
|
||||
body []byte
|
||||
url *url.URL
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
// mime type to check if a media type matches
|
||||
reJsonMimeType = regexp.MustCompile(`application/(?:\w+\+)?json`)
|
||||
isJSONMimeType = regexp.MustCompile(`application/(?:\w+\+)?json`).MatchString
|
||||
// ValidateResponse validates an HTTP response and returns an [E.Either] if the response is not a success
|
||||
ValidateResponse = E.FromPredicate(isValidStatus, StatusCodeError)
|
||||
// alidateJsonContentTypeString parses a content type a validates that it is valid JSON
|
||||
validateJsonContentTypeString = F.Flow2(
|
||||
validateJSONContentTypeString = F.Flow2(
|
||||
ParseMediaType,
|
||||
E.ChainFirst(F.Flow2(
|
||||
T.First[string, map[string]string],
|
||||
E.FromPredicate(reJsonMimeType.MatchString, func(mimeType string) error {
|
||||
return fmt.Errorf("mimetype [%s] is not a valid JSON content type", mimeType)
|
||||
}),
|
||||
P.Head[string, map[string]string],
|
||||
E.FromPredicate(isJSONMimeType, errors.OnSome[string]("mimetype [%s] is not a valid JSON content type")),
|
||||
)),
|
||||
)
|
||||
// ValidateJsonResponse checks if an HTTP response is a valid JSON response
|
||||
ValidateJsonResponse = F.Flow2(
|
||||
// ValidateJSONResponse checks if an HTTP response is a valid JSON response
|
||||
ValidateJSONResponse = F.Flow2(
|
||||
E.Of[error, *H.Response],
|
||||
E.ChainFirst(F.Flow5(
|
||||
GetHeader,
|
||||
R.Lookup[H.Header](HeaderContentType),
|
||||
O.Chain(A.First[string]),
|
||||
E.FromOption[string](errors.OnNone("unable to access the [%s] header", HeaderContentType)),
|
||||
E.ChainFirst(validateJsonContentTypeString),
|
||||
E.ChainFirst(validateJSONContentTypeString),
|
||||
)))
|
||||
// ValidateJsonResponse checks if an HTTP response is a valid JSON response
|
||||
//
|
||||
// Deprecated: use [ValidateJSONResponse] instead
|
||||
ValidateJsonResponse = ValidateJSONResponse
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -69,7 +79,32 @@ const (
|
||||
// ParseMediaType parses a media type into a tuple
|
||||
func ParseMediaType(mediaType string) E.Either[error, ParsedMediaType] {
|
||||
m, p, err := mime.ParseMediaType(mediaType)
|
||||
return E.TryCatchError(T.MakeTuple2(m, p), err)
|
||||
return E.TryCatchError(P.MakePair(m, p), err)
|
||||
}
|
||||
|
||||
// Error fulfills the error interface
|
||||
func (r *HttpError) Error() string {
|
||||
return fmt.Sprintf("invalid status code [%d] when accessing URL [%s]", r.statusCode, r.url)
|
||||
}
|
||||
|
||||
func (r *HttpError) String() string {
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
func (r *HttpError) StatusCode() int {
|
||||
return r.statusCode
|
||||
}
|
||||
|
||||
func (r *HttpError) Headers() H.Header {
|
||||
return r.headers
|
||||
}
|
||||
|
||||
func (r *HttpError) URL() *url.URL {
|
||||
return r.url
|
||||
}
|
||||
|
||||
func (r *HttpError) Body() []byte {
|
||||
return r.body
|
||||
}
|
||||
|
||||
func GetHeader(resp *H.Response) H.Header {
|
||||
@@ -84,6 +119,13 @@ func isValidStatus(resp *H.Response) bool {
|
||||
return resp.StatusCode >= H.StatusOK && resp.StatusCode < H.StatusMultipleChoices
|
||||
}
|
||||
|
||||
// StatusCodeError creates an instance of [HttpError] filled with information from the response
|
||||
func StatusCodeError(resp *H.Response) error {
|
||||
return fmt.Errorf("invalid status code [%d] when accessing URL [%s]", resp.StatusCode, resp.Request.URL)
|
||||
// read the body
|
||||
bodyRdr := GetBody(resp)
|
||||
defer bodyRdr.Close()
|
||||
// try to access body content
|
||||
body, _ := io.ReadAll(bodyRdr)
|
||||
// return an error with comprehensive information
|
||||
return &HttpError{statusCode: resp.StatusCode, headers: GetHeader(resp).Clone(), body: body, url: resp.Request.URL}
|
||||
}
|
||||
|
@@ -39,7 +39,7 @@ func Error[A any](t *testing.T) func(E.Either[error, A]) bool {
|
||||
func TestValidateJsonContentTypeString(t *testing.T) {
|
||||
|
||||
res := F.Pipe1(
|
||||
validateJsonContentTypeString(C.Json),
|
||||
validateJSONContentTypeString(C.JSON),
|
||||
NoError[ParsedMediaType](t),
|
||||
)
|
||||
|
||||
@@ -49,7 +49,7 @@ func TestValidateJsonContentTypeString(t *testing.T) {
|
||||
func TestValidateInvalidJsonContentTypeString(t *testing.T) {
|
||||
|
||||
res := F.Pipe1(
|
||||
validateJsonContentTypeString("application/xml"),
|
||||
validateJSONContentTypeString("application/xml"),
|
||||
Error[ParsedMediaType](t),
|
||||
)
|
||||
|
||||
|
89
identity/bind.go
Normal file
89
identity/bind.go
Normal file
@@ -0,0 +1,89 @@
|
||||
// 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 identity
|
||||
|
||||
import (
|
||||
A "github.com/IBM/fp-go/internal/apply"
|
||||
C "github.com/IBM/fp-go/internal/chain"
|
||||
F "github.com/IBM/fp-go/internal/functor"
|
||||
)
|
||||
|
||||
// Bind creates an empty context of type [S] to be used with the [Bind] operation
|
||||
func Do[S any](
|
||||
empty S,
|
||||
) S {
|
||||
return empty
|
||||
}
|
||||
|
||||
// Bind attaches the result of a computation to a context [S1] to produce a context [S2]
|
||||
func Bind[S1, S2, T any](
|
||||
setter func(T) func(S1) S2,
|
||||
f func(S1) T,
|
||||
) func(S1) S2 {
|
||||
return C.Bind(
|
||||
Chain[S1, S2],
|
||||
Map[T, S2],
|
||||
setter,
|
||||
f,
|
||||
)
|
||||
}
|
||||
|
||||
// Let attaches the result of a computation to a context [S1] to produce a context [S2]
|
||||
func Let[S1, S2, T any](
|
||||
key func(T) func(S1) S2,
|
||||
f func(S1) T,
|
||||
) func(S1) S2 {
|
||||
return F.Let(
|
||||
Map[S1, S2],
|
||||
key,
|
||||
f,
|
||||
)
|
||||
}
|
||||
|
||||
// LetTo attaches the a value to a context [S1] to produce a context [S2]
|
||||
func LetTo[S1, S2, B any](
|
||||
key func(B) func(S1) S2,
|
||||
b B,
|
||||
) func(S1) S2 {
|
||||
return F.LetTo(
|
||||
Map[S1, S2],
|
||||
key,
|
||||
b,
|
||||
)
|
||||
}
|
||||
|
||||
// BindTo initializes a new state [S1] from a value [T]
|
||||
func BindTo[S1, T any](
|
||||
setter func(T) S1,
|
||||
) func(T) S1 {
|
||||
return C.BindTo(
|
||||
Map[T, S1],
|
||||
setter,
|
||||
)
|
||||
}
|
||||
|
||||
// ApS attaches a value to a context [S1] to produce a context [S2] by considering the context and the value concurrently
|
||||
func ApS[S1, S2, T any](
|
||||
setter func(T) func(S1) S2,
|
||||
fa T,
|
||||
) func(S1) S2 {
|
||||
return A.ApS(
|
||||
Ap[S2, T],
|
||||
Map[S1, func(T) S2],
|
||||
setter,
|
||||
fa,
|
||||
)
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
// Code generated by go generate; DO NOT EDIT.
|
||||
// This file was generated by robots at
|
||||
// 2023-10-23 08:30:50.5492271 +0200 CEST m=+0.023274501
|
||||
// 2024-02-29 16:19:02.7798504 +0100 CET m=+0.021933401
|
||||
|
||||
package identity
|
||||
|
||||
|
@@ -50,7 +50,11 @@ func MonadChainFirst[GAB ~func(A) B, A, B any](fa A, f GAB) A {
|
||||
}
|
||||
|
||||
func ChainFirst[GAB ~func(A) B, A, B any](f GAB) func(A) A {
|
||||
return C.ChainFirst(MonadChain[func(A) A, A, A], MonadMap[func(B) A, B, A], f)
|
||||
return C.ChainFirst(
|
||||
Chain[func(A) A, A, A],
|
||||
Map[func(B) A, B, A],
|
||||
f,
|
||||
)
|
||||
}
|
||||
|
||||
func MonadFlap[GAB ~func(A) B, A, B any](fab GAB, a A) B {
|
||||
@@ -58,5 +62,5 @@ func MonadFlap[GAB ~func(A) B, A, B any](fab GAB, a A) B {
|
||||
}
|
||||
|
||||
func Flap[GAB ~func(A) B, B, A any](a A) func(GAB) B {
|
||||
return F.Bind2nd(MonadFlap[GAB, A, B], a)
|
||||
return FC.Flap(Map[func(GAB) B, GAB, B], a)
|
||||
}
|
||||
|
@@ -36,7 +36,7 @@ func Map[A, B any](f func(A) B) func(A) B {
|
||||
return G.Map(f)
|
||||
}
|
||||
|
||||
func MonadMapTo[A, B any](fa A, b B) B {
|
||||
func MonadMapTo[A, B any](_ A, b B) B {
|
||||
return b
|
||||
}
|
||||
|
||||
|
43
identity/monad.go
Normal file
43
identity/monad.go
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2024 IBM Corp.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package identity
|
||||
|
||||
import (
|
||||
"github.com/IBM/fp-go/internal/monad"
|
||||
)
|
||||
|
||||
type identityMonad[A, B any] struct{}
|
||||
|
||||
func (o *identityMonad[A, B]) Of(a A) A {
|
||||
return Of[A](a)
|
||||
}
|
||||
|
||||
func (o *identityMonad[A, B]) Map(f func(A) B) func(A) B {
|
||||
return Map[A, B](f)
|
||||
}
|
||||
|
||||
func (o *identityMonad[A, B]) Chain(f func(A) B) func(A) B {
|
||||
return Chain[A, B](f)
|
||||
}
|
||||
|
||||
func (o *identityMonad[A, B]) Ap(fa A) func(func(A) B) B {
|
||||
return Ap[B, A](fa)
|
||||
}
|
||||
|
||||
// Monad implements the monadic operations for [Option]
|
||||
func Monad[A, B any]() monad.Monad[A, B, A, B, func(A) B] {
|
||||
return &identityMonad[A, B]{}
|
||||
}
|
@@ -20,13 +20,19 @@ import (
|
||||
|
||||
E "github.com/IBM/fp-go/eq"
|
||||
F "github.com/IBM/fp-go/function"
|
||||
"github.com/IBM/fp-go/internal/applicative"
|
||||
"github.com/IBM/fp-go/internal/apply"
|
||||
L "github.com/IBM/fp-go/internal/apply/testing"
|
||||
"github.com/IBM/fp-go/internal/functor"
|
||||
"github.com/IBM/fp-go/internal/pointed"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// Applicative identity law
|
||||
//
|
||||
// A.ap(A.of(a => a), fa) <-> fa
|
||||
//
|
||||
// Deprecated: use [ApplicativeAssertIdentity]
|
||||
func AssertIdentity[HKTA, HKTAA, A any](t *testing.T,
|
||||
eq E.Eq[HKTA],
|
||||
|
||||
@@ -34,6 +40,9 @@ func AssertIdentity[HKTA, HKTAA, A any](t *testing.T,
|
||||
|
||||
fap func(HKTAA, HKTA) HKTA,
|
||||
) func(fa HKTA) bool {
|
||||
// mark as test helper
|
||||
t.Helper()
|
||||
|
||||
return func(fa HKTA) bool {
|
||||
|
||||
left := fap(fof(F.Identity[A]), fa)
|
||||
@@ -43,9 +52,33 @@ func AssertIdentity[HKTA, HKTAA, A any](t *testing.T,
|
||||
}
|
||||
}
|
||||
|
||||
// Applicative identity law
|
||||
//
|
||||
// A.ap(A.of(a => a), fa) <-> fa
|
||||
func ApplicativeAssertIdentity[HKTA, HKTFAA, A any](t *testing.T,
|
||||
eq E.Eq[HKTA],
|
||||
|
||||
ap applicative.Applicative[A, A, HKTA, HKTA, HKTFAA],
|
||||
paa pointed.Pointed[func(A) A, HKTFAA],
|
||||
|
||||
) func(fa HKTA) bool {
|
||||
// mark as test helper
|
||||
t.Helper()
|
||||
|
||||
return func(fa HKTA) bool {
|
||||
|
||||
left := ap.Ap(fa)(paa.Of(F.Identity[A]))
|
||||
right := fa
|
||||
|
||||
return assert.True(t, eq.Equals(left, right), "Applicative identity")
|
||||
}
|
||||
}
|
||||
|
||||
// Applicative homomorphism law
|
||||
//
|
||||
// A.ap(A.of(ab), A.of(a)) <-> A.of(ab(a))
|
||||
//
|
||||
// Deprecated: use [ApplicativeAssertHomomorphism]
|
||||
func AssertHomomorphism[HKTA, HKTB, HKTAB, A, B any](t *testing.T,
|
||||
eq E.Eq[HKTB],
|
||||
|
||||
@@ -57,6 +90,9 @@ func AssertHomomorphism[HKTA, HKTB, HKTAB, A, B any](t *testing.T,
|
||||
|
||||
ab func(A) B,
|
||||
) func(a A) bool {
|
||||
// mark as test helper
|
||||
t.Helper()
|
||||
|
||||
return func(a A) bool {
|
||||
|
||||
left := fap(fofab(ab), fofa(a))
|
||||
@@ -66,14 +102,39 @@ func AssertHomomorphism[HKTA, HKTB, HKTAB, A, B any](t *testing.T,
|
||||
}
|
||||
}
|
||||
|
||||
// Applicative homomorphism law
|
||||
//
|
||||
// A.ap(A.of(ab), A.of(a)) <-> A.of(ab(a))
|
||||
func ApplicativeAssertHomomorphism[HKTA, HKTB, HKTFAB, A, B any](t *testing.T,
|
||||
eq E.Eq[HKTB],
|
||||
|
||||
apab applicative.Applicative[A, B, HKTA, HKTB, HKTFAB],
|
||||
pb pointed.Pointed[B, HKTB],
|
||||
pfab pointed.Pointed[func(A) B, HKTFAB],
|
||||
|
||||
ab func(A) B,
|
||||
) func(a A) bool {
|
||||
// mark as test helper
|
||||
t.Helper()
|
||||
|
||||
return func(a A) bool {
|
||||
|
||||
left := apab.Ap(apab.Of(a))(pfab.Of(ab))
|
||||
right := pb.Of(ab(a))
|
||||
|
||||
return assert.True(t, eq.Equals(left, right), "Applicative homomorphism")
|
||||
}
|
||||
}
|
||||
|
||||
// Applicative interchange law
|
||||
//
|
||||
// A.ap(fab, A.of(a)) <-> A.ap(A.of(ab => ab(a)), fab)
|
||||
//
|
||||
// Deprecated: use [ApplicativeAssertInterchange]
|
||||
func AssertInterchange[HKTA, HKTB, HKTAB, HKTABB, A, B any](t *testing.T,
|
||||
eq E.Eq[HKTB],
|
||||
|
||||
fofa func(A) HKTA,
|
||||
fofb func(B) HKTB,
|
||||
fofab func(func(A) B) HKTAB,
|
||||
fofabb func(func(func(A) B) B) HKTABB,
|
||||
|
||||
@@ -82,6 +143,9 @@ func AssertInterchange[HKTA, HKTB, HKTAB, HKTABB, A, B any](t *testing.T,
|
||||
|
||||
ab func(A) B,
|
||||
) func(a A) bool {
|
||||
// mark as test helper
|
||||
t.Helper()
|
||||
|
||||
return func(a A) bool {
|
||||
|
||||
fab := fofab(ab)
|
||||
@@ -95,7 +159,38 @@ func AssertInterchange[HKTA, HKTB, HKTAB, HKTABB, A, B any](t *testing.T,
|
||||
}
|
||||
}
|
||||
|
||||
// Applicative interchange law
|
||||
//
|
||||
// A.ap(fab, A.of(a)) <-> A.ap(A.of(ab => ab(a)), fab)
|
||||
func ApplicativeAssertInterchange[HKTA, HKTB, HKTFAB, HKTABB, A, B any](t *testing.T,
|
||||
eq E.Eq[HKTB],
|
||||
|
||||
apab applicative.Applicative[A, B, HKTA, HKTB, HKTFAB],
|
||||
apabb applicative.Applicative[func(A) B, B, HKTFAB, HKTB, HKTABB],
|
||||
pabb pointed.Pointed[func(func(A) B) B, HKTABB],
|
||||
|
||||
ab func(A) B,
|
||||
) func(a A) bool {
|
||||
// mark as test helper
|
||||
t.Helper()
|
||||
|
||||
return func(a A) bool {
|
||||
|
||||
fab := apabb.Of(ab)
|
||||
|
||||
left := apab.Ap(apab.Of(a))(fab)
|
||||
|
||||
right := apabb.Ap(fab)(pabb.Of(func(ab func(A) B) B {
|
||||
return ab(a)
|
||||
}))
|
||||
|
||||
return assert.True(t, eq.Equals(left, right), "Applicative homomorphism")
|
||||
}
|
||||
}
|
||||
|
||||
// AssertLaws asserts the apply laws `identity`, `composition`, `associative composition`, 'applicative identity', 'homomorphism', 'interchange'
|
||||
//
|
||||
// Deprecated: use [ApplicativeAssertLaws] instead
|
||||
func AssertLaws[HKTA, HKTB, HKTC, HKTAA, HKTAB, HKTBC, HKTAC, HKTABB, HKTABAC, A, B, C any](t *testing.T,
|
||||
eqa E.Eq[HKTA],
|
||||
eqb E.Eq[HKTB],
|
||||
@@ -127,15 +222,62 @@ func AssertLaws[HKTA, HKTB, HKTC, HKTAA, HKTAB, HKTBC, HKTAC, HKTABB, HKTABAC, A
|
||||
ab func(A) B,
|
||||
bc func(B) C,
|
||||
) func(a A) bool {
|
||||
// mark as test helper
|
||||
t.Helper()
|
||||
|
||||
// apply laws
|
||||
apply := L.AssertLaws(t, eqa, eqc, fofab, fofbc, faa, fab, fac, fbc, fmap, fapab, fapbc, fapac, fapabac, ab, bc)
|
||||
// applicative laws
|
||||
identity := AssertIdentity(t, eqa, fofaa, fapaa)
|
||||
homomorphism := AssertHomomorphism(t, eqb, fofa, fofb, fofab, fapab, ab)
|
||||
interchange := AssertInterchange(t, eqb, fofa, fofb, fofab, fofabb, fapab, fapabb, ab)
|
||||
interchange := AssertInterchange(t, eqb, fofa, fofab, fofabb, fapab, fapabb, ab)
|
||||
|
||||
return func(a A) bool {
|
||||
fa := fofa(a)
|
||||
return apply(fa) && identity(fa) && homomorphism(a) && interchange(a)
|
||||
}
|
||||
}
|
||||
|
||||
// ApplicativeAssertLaws asserts the apply laws `identity`, `composition`, `associative composition`, 'applicative identity', 'homomorphism', 'interchange'
|
||||
func ApplicativeAssertLaws[HKTA, HKTB, HKTC, HKTAA, HKTAB, HKTBC, HKTAC, HKTABB, HKTABAC, A, B, C any](t *testing.T,
|
||||
eqa E.Eq[HKTA],
|
||||
eqb E.Eq[HKTB],
|
||||
eqc E.Eq[HKTC],
|
||||
|
||||
fofb pointed.Pointed[B, HKTB],
|
||||
|
||||
fofaa pointed.Pointed[func(A) A, HKTAA],
|
||||
fofbc pointed.Pointed[func(B) C, HKTBC],
|
||||
|
||||
fofabb pointed.Pointed[func(func(A) B) B, HKTABB],
|
||||
|
||||
faa functor.Functor[A, A, HKTA, HKTA],
|
||||
|
||||
fmap functor.Functor[func(B) C, func(func(A) B) func(A) C, HKTBC, HKTABAC],
|
||||
|
||||
fapaa applicative.Applicative[A, A, HKTA, HKTA, HKTAA],
|
||||
fapab applicative.Applicative[A, B, HKTA, HKTB, HKTAB],
|
||||
fapbc apply.Apply[B, C, HKTB, HKTC, HKTBC],
|
||||
fapac apply.Apply[A, C, HKTA, HKTC, HKTAC],
|
||||
|
||||
fapabb applicative.Applicative[func(A) B, B, HKTAB, HKTB, HKTABB],
|
||||
fapabac applicative.Applicative[func(A) B, func(A) C, HKTAB, HKTAC, HKTABAC],
|
||||
|
||||
ab func(A) B,
|
||||
bc func(B) C,
|
||||
) func(a A) bool {
|
||||
// mark as test helper
|
||||
t.Helper()
|
||||
|
||||
// apply laws
|
||||
apply := L.ApplyAssertLaws(t, eqa, eqc, applicative.ToPointed(fapabac), fofbc, faa, fmap, applicative.ToApply(fapab), fapbc, fapac, applicative.ToApply(fapabac), ab, bc)
|
||||
// applicative laws
|
||||
identity := ApplicativeAssertIdentity(t, eqa, fapaa, fofaa)
|
||||
homomorphism := ApplicativeAssertHomomorphism(t, eqb, fapab, fofb, applicative.ToPointed(fapabb), ab)
|
||||
interchange := ApplicativeAssertInterchange(t, eqb, fapab, fapabb, fofabb, ab)
|
||||
|
||||
return func(a A) bool {
|
||||
fa := fapaa.Of(a)
|
||||
return apply(fa) && identity(fa) && homomorphism(a) && interchange(a)
|
||||
}
|
||||
}
|
||||
|
42
internal/applicative/types.go
Normal file
42
internal/applicative/types.go
Normal 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 applicative
|
||||
|
||||
import (
|
||||
"github.com/IBM/fp-go/internal/apply"
|
||||
"github.com/IBM/fp-go/internal/functor"
|
||||
"github.com/IBM/fp-go/internal/pointed"
|
||||
)
|
||||
|
||||
type Applicative[A, B, HKTA, HKTB, HKTFAB any] interface {
|
||||
apply.Apply[A, B, HKTA, HKTB, HKTFAB]
|
||||
pointed.Pointed[A, HKTA]
|
||||
}
|
||||
|
||||
// ToFunctor converts from [Applicative] to [functor.Functor]
|
||||
func ToFunctor[A, B, HKTA, HKTB, HKTFAB any](ap Applicative[A, B, HKTA, HKTB, HKTFAB]) functor.Functor[A, B, HKTA, HKTB] {
|
||||
return ap
|
||||
}
|
||||
|
||||
// ToApply converts from [Applicative] to [apply.Apply]
|
||||
func ToApply[A, B, HKTA, HKTB, HKTFAB any](ap Applicative[A, B, HKTA, HKTB, HKTFAB]) apply.Apply[A, B, HKTA, HKTB, HKTFAB] {
|
||||
return ap
|
||||
}
|
||||
|
||||
// ToPointed converts from [Applicative] to [pointed.Pointed]
|
||||
func ToPointed[A, B, HKTA, HKTB, HKTFAB any](ap Applicative[A, B, HKTA, HKTB, HKTFAB]) pointed.Pointed[A, HKTA] {
|
||||
return ap
|
||||
}
|
@@ -19,13 +19,6 @@ import (
|
||||
F "github.com/IBM/fp-go/function"
|
||||
)
|
||||
|
||||
// HKTFGA = HKT<F, HKT<G, A>>
|
||||
// HKTFGB = HKT<F, HKT<G, B>>
|
||||
// HKTFGAB = HKT<F, HKT<G, (a: A) => B>>
|
||||
|
||||
// HKTGA = HKT<G, A>
|
||||
// HKTGB = HKT<G, B>
|
||||
// HKTGAB = HKT<G, (a: A) => B>
|
||||
func MonadAp[HKTGA, HKTGB, HKTGAB, HKTFGAB, HKTFGGAB, HKTFGA, HKTFGB any](
|
||||
fap func(HKTFGGAB, HKTFGA) HKTFGB,
|
||||
fmap func(HKTFGAB, func(HKTGAB) func(HKTGA) HKTGB) HKTFGGAB,
|
||||
@@ -37,6 +30,29 @@ func MonadAp[HKTGA, HKTGB, HKTGAB, HKTFGAB, HKTFGGAB, HKTFGA, HKTFGB any](
|
||||
return fap(fmap(fab, F.Bind1st(F.Bind1st[HKTGAB, HKTGA, HKTGB], gap)), fa)
|
||||
}
|
||||
|
||||
func Ap[HKTGA, HKTGB, HKTGAB, HKTFGAB, HKTFGGAB, HKTFGA, HKTFGB any](
|
||||
fap func(HKTFGA) func(HKTFGGAB) HKTFGB,
|
||||
fmap func(func(HKTGAB) func(HKTGA) HKTGB) func(HKTFGAB) HKTFGGAB,
|
||||
gap func(HKTGA) func(HKTGAB) HKTGB,
|
||||
|
||||
fa HKTFGA) func(HKTFGAB) HKTFGB {
|
||||
|
||||
return F.Flow2(
|
||||
fmap(F.Flip(gap)),
|
||||
fap(fa),
|
||||
)
|
||||
}
|
||||
|
||||
// func Ap[HKTGA, HKTGB, HKTGAB, HKTFGAB, HKTFGGAB, HKTFGA, HKTFGB any](
|
||||
// fap func(HKTFGA) func(HKTFGGAB) HKTFGB,
|
||||
// fmap func(func(HKTGAB) func(HKTGA) HKTGB) func(HKTFGAB) HKTFGGAB,
|
||||
// gap func(HKTGA) func(HKTGAB) HKTGB,
|
||||
|
||||
// fa HKTFGA) func(HKTFGAB) HKTFGB {
|
||||
|
||||
// return fap(fmap(F.Bind1st(F.Bind1st[HKTGAB, HKTGA, HKTGB], gap)), fa)
|
||||
// }
|
||||
|
||||
// export function ap<F, G>(
|
||||
// F: Apply<F>,
|
||||
// G: Apply<G>
|
||||
@@ -107,3 +123,25 @@ func ApSecond[HKTGA, HKTGB, HKTGBB, A, B any](
|
||||
return MonadApSecond(fap, fmap, first, second)
|
||||
}
|
||||
}
|
||||
|
||||
func MonadApS[S1, S2, B, HKTBGBS2, HKTS1, HKTS2, HKTB any](
|
||||
fap func(HKTBGBS2, HKTB) HKTS2,
|
||||
fmap func(HKTS1, func(S1) func(B) S2) HKTBGBS2,
|
||||
fa HKTS1,
|
||||
key func(B) func(S1) S2,
|
||||
fb HKTB,
|
||||
) HKTS2 {
|
||||
return fap(fmap(fa, F.Flip(key)), fb)
|
||||
}
|
||||
|
||||
func ApS[S1, S2, B, HKTBGBS2, HKTS1, HKTS2, HKTB any](
|
||||
fap func(HKTB) func(HKTBGBS2) HKTS2,
|
||||
fmap func(func(S1) func(B) S2) func(HKTS1) HKTBGBS2,
|
||||
key func(B) func(S1) S2,
|
||||
fb HKTB,
|
||||
) func(HKTS1) HKTS2 {
|
||||
return F.Flow2(
|
||||
fmap(F.Flip(key)),
|
||||
fap(fb),
|
||||
)
|
||||
}
|
||||
|
@@ -15,4 +15,4 @@
|
||||
|
||||
package apply
|
||||
|
||||
//go:generate go run ../.. apply --count 10 --filename gen.go
|
||||
//go:generate go run ../.. apply --count 15 --filename gen.go
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -19,13 +19,18 @@ import (
|
||||
"testing"
|
||||
|
||||
E "github.com/IBM/fp-go/eq"
|
||||
"github.com/IBM/fp-go/internal/apply"
|
||||
"github.com/IBM/fp-go/internal/functor"
|
||||
FCT "github.com/IBM/fp-go/internal/functor/testing"
|
||||
"github.com/IBM/fp-go/internal/pointed"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// Apply associative composition law
|
||||
//
|
||||
// F.ap(F.ap(F.map(fbc, bc => ab => a => bc(ab(a))), fab), fa) <-> F.ap(fbc, F.ap(fab, fa))
|
||||
//
|
||||
// Deprecated: use [ApplyAssertAssociativeComposition] instead
|
||||
func AssertAssociativeComposition[HKTA, HKTB, HKTC, HKTAB, HKTBC, HKTAC, HKTABAC, A, B, C any](t *testing.T,
|
||||
eq E.Eq[HKTC],
|
||||
|
||||
@@ -43,6 +48,7 @@ func AssertAssociativeComposition[HKTA, HKTB, HKTC, HKTAB, HKTBC, HKTAC, HKTABAC
|
||||
ab func(A) B,
|
||||
bc func(B) C,
|
||||
) func(fa HKTA) bool {
|
||||
t.Helper()
|
||||
return func(fa HKTA) bool {
|
||||
|
||||
fab := fofab(ab)
|
||||
@@ -62,7 +68,49 @@ func AssertAssociativeComposition[HKTA, HKTB, HKTC, HKTAB, HKTBC, HKTAC, HKTABAC
|
||||
}
|
||||
}
|
||||
|
||||
// Apply associative composition law
|
||||
//
|
||||
// F.ap(F.ap(F.map(fbc, bc => ab => a => bc(ab(a))), fab), fa) <-> F.ap(fbc, F.ap(fab, fa))
|
||||
func ApplyAssertAssociativeComposition[HKTA, HKTB, HKTC, HKTAB, HKTBC, HKTAC, HKTABAC, A, B, C any](t *testing.T,
|
||||
eq E.Eq[HKTC],
|
||||
|
||||
fofab pointed.Pointed[func(A) B, HKTAB],
|
||||
fofbc pointed.Pointed[func(B) C, HKTBC],
|
||||
|
||||
fmap functor.Functor[func(B) C, func(func(A) B) func(A) C, HKTBC, HKTABAC],
|
||||
|
||||
fapab apply.Apply[A, B, HKTA, HKTB, HKTAB],
|
||||
fapbc apply.Apply[B, C, HKTB, HKTC, HKTBC],
|
||||
fapac apply.Apply[A, C, HKTA, HKTC, HKTAC],
|
||||
|
||||
fapabac apply.Apply[func(A) B, func(A) C, HKTAB, HKTAC, HKTABAC],
|
||||
|
||||
ab func(A) B,
|
||||
bc func(B) C,
|
||||
) func(fa HKTA) bool {
|
||||
t.Helper()
|
||||
return func(fa HKTA) bool {
|
||||
|
||||
fab := fofab.Of(ab)
|
||||
fbc := fofbc.Of(bc)
|
||||
|
||||
left := fapac.Ap(fa)(fapabac.Ap(fab)(fmap.Map(func(bc func(B) C) func(func(A) B) func(A) C {
|
||||
return func(ab func(A) B) func(A) C {
|
||||
return func(a A) C {
|
||||
return bc(ab(a))
|
||||
}
|
||||
}
|
||||
})(fbc)))
|
||||
|
||||
right := fapbc.Ap(fapab.Ap(fa)(fab))(fbc)
|
||||
|
||||
return assert.True(t, eq.Equals(left, right), "Apply associative composition")
|
||||
}
|
||||
}
|
||||
|
||||
// AssertLaws asserts the apply laws `identity`, `composition` and `associative composition`
|
||||
//
|
||||
// Deprecated: use [ApplyAssertLaws] instead
|
||||
func AssertLaws[HKTA, HKTB, HKTC, HKTAB, HKTBC, HKTAC, HKTABAC, A, B, C any](t *testing.T,
|
||||
eqa E.Eq[HKTA],
|
||||
eqc E.Eq[HKTC],
|
||||
@@ -86,6 +134,8 @@ func AssertLaws[HKTA, HKTB, HKTC, HKTAB, HKTBC, HKTAC, HKTABAC, A, B, C any](t *
|
||||
ab func(A) B,
|
||||
bc func(B) C,
|
||||
) func(fa HKTA) bool {
|
||||
// mark as test helper
|
||||
t.Helper()
|
||||
// functor laws
|
||||
functor := FCT.AssertLaws(t, eqa, eqc, faa, fab, fac, fbc, ab, bc)
|
||||
// associative composition laws
|
||||
@@ -95,3 +145,36 @@ func AssertLaws[HKTA, HKTB, HKTC, HKTAB, HKTBC, HKTAC, HKTABAC, A, B, C any](t *
|
||||
return functor(fa) && composition(fa)
|
||||
}
|
||||
}
|
||||
|
||||
// ApplyAssertLaws asserts the apply laws `identity`, `composition` and `associative composition`
|
||||
func ApplyAssertLaws[HKTA, HKTB, HKTC, HKTAB, HKTBC, HKTAC, HKTABAC, A, B, C any](t *testing.T,
|
||||
eqa E.Eq[HKTA],
|
||||
eqc E.Eq[HKTC],
|
||||
|
||||
fofab pointed.Pointed[func(A) B, HKTAB],
|
||||
fofbc pointed.Pointed[func(B) C, HKTBC],
|
||||
|
||||
faa functor.Functor[A, A, HKTA, HKTA],
|
||||
|
||||
fmap functor.Functor[func(B) C, func(func(A) B) func(A) C, HKTBC, HKTABAC],
|
||||
|
||||
fapab apply.Apply[A, B, HKTA, HKTB, HKTAB],
|
||||
fapbc apply.Apply[B, C, HKTB, HKTC, HKTBC],
|
||||
fapac apply.Apply[A, C, HKTA, HKTC, HKTAC],
|
||||
|
||||
fapabac apply.Apply[func(A) B, func(A) C, HKTAB, HKTAC, HKTABAC],
|
||||
|
||||
ab func(A) B,
|
||||
bc func(B) C,
|
||||
) func(fa HKTA) bool {
|
||||
// mark as test helper
|
||||
t.Helper()
|
||||
// functor laws
|
||||
functor := FCT.FunctorAssertLaws(t, eqa, eqc, faa, apply.ToFunctor(fapab), apply.ToFunctor(fapac), apply.ToFunctor(fapbc), ab, bc)
|
||||
// associative composition laws
|
||||
composition := ApplyAssertAssociativeComposition(t, eqc, fofab, fofbc, fmap, fapab, fapbc, fapac, fapabac, ab, bc)
|
||||
|
||||
return func(fa HKTA) bool {
|
||||
return functor(fa) && composition(fa)
|
||||
}
|
||||
}
|
||||
|
30
internal/apply/types.go
Normal file
30
internal/apply/types.go
Normal file
@@ -0,0 +1,30 @@
|
||||
// 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 apply
|
||||
|
||||
import (
|
||||
"github.com/IBM/fp-go/internal/functor"
|
||||
)
|
||||
|
||||
type Apply[A, B, HKTA, HKTB, HKTFAB any] interface {
|
||||
functor.Functor[A, B, HKTA, HKTB]
|
||||
Ap(HKTA) func(HKTFAB) HKTB
|
||||
}
|
||||
|
||||
// ToFunctor converts from [Apply] to [functor.Functor]
|
||||
func ToFunctor[A, B, HKTA, HKTB, HKTFAB any](ap Apply[A, B, HKTA, HKTB, HKTFAB]) functor.Functor[A, B, HKTA, HKTB] {
|
||||
return ap
|
||||
}
|
@@ -106,6 +106,12 @@ func MonadMap[GA ~[]A, GB ~[]B, A, B any](as GA, f func(a A) B) GB {
|
||||
return bs
|
||||
}
|
||||
|
||||
func Map[GA ~[]A, GB ~[]B, A, B any](f func(a A) B) func(GA) GB {
|
||||
return func(as GA) GB {
|
||||
return MonadMap[GA, GB](as, f)
|
||||
}
|
||||
}
|
||||
|
||||
func MonadMapWithIndex[GA ~[]A, GB ~[]B, A, B any](as GA, f func(idx int, a A) B) GB {
|
||||
count := len(as)
|
||||
bs := make(GB, count)
|
||||
|
@@ -1,75 +0,0 @@
|
||||
// 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 bindt
|
||||
|
||||
import (
|
||||
F "github.com/IBM/fp-go/function"
|
||||
I "github.com/IBM/fp-go/identity"
|
||||
T "github.com/IBM/fp-go/tuple"
|
||||
)
|
||||
|
||||
func Bind[SET ~func(B) func(S1) S2, FCT ~func(S1) HKTB, S1, S2, B, HKTS1, HKTS2, HKTB any](
|
||||
mchain func(func(S1) HKTS2) func(HKTS1) HKTS2,
|
||||
mmap func(func(B) S2) func(HKTB) HKTS2,
|
||||
s SET,
|
||||
f FCT,
|
||||
) func(HKTS1) HKTS2 {
|
||||
return mchain(F.Flow3(
|
||||
T.Replicate2[S1],
|
||||
T.Map2(F.Flow2(
|
||||
I.Ap[S2, S1],
|
||||
F.Flow2(
|
||||
F.Bind1st(F.Flow2[SET, func(func(S1) S2) S2], s),
|
||||
mmap,
|
||||
)), f),
|
||||
T.Tupled2(I.MonadAp[HKTS2, HKTB]),
|
||||
))
|
||||
}
|
||||
|
||||
func BindTo[SET ~func(B) S2, S2, B, HKTS2, HKTB any](
|
||||
mmap func(func(B) S2) func(HKTB) HKTS2,
|
||||
s SET,
|
||||
) func(HKTB) HKTS2 {
|
||||
return mmap(s)
|
||||
}
|
||||
|
||||
func ApS[
|
||||
SET ~func(B) func(S1) S2,
|
||||
S1, S2, B, HKTS1S2, HKTS1, HKTS2, HKTB any,
|
||||
](
|
||||
ap func(HKTS1) func(HKTS1S2) HKTS2,
|
||||
mmap func(func(B) func(S1) S2) func(HKTB) HKTS1S2,
|
||||
s SET, fb HKTB) func(HKTS1) HKTS2 {
|
||||
|
||||
return F.Flow2(
|
||||
ap,
|
||||
I.Ap[HKTS2, HKTS1S2](mmap(s)(fb)),
|
||||
)
|
||||
}
|
||||
|
||||
func Let[SET ~func(B) func(S1) S2, FCT ~func(S1) B, S1, S2, B, HKTS1, HKTS2 any](
|
||||
mmap func(func(S1) S2) func(HKTS1) HKTS2,
|
||||
s SET,
|
||||
f FCT,
|
||||
) func(HKTS1) HKTS2 {
|
||||
return mmap(F.Flow3(
|
||||
T.Replicate2[S1],
|
||||
T.Map2(F.Flow2(
|
||||
I.Ap[S2, S1],
|
||||
F.Bind1st(F.Flow2[SET, func(func(S1) S2) S2], s)), f),
|
||||
T.Tupled2(I.MonadAp[S2, B]),
|
||||
))
|
||||
}
|
@@ -43,19 +43,68 @@ func MonadChain[A, B, HKTA, HKTB any](
|
||||
// HKTA=HKT[A]
|
||||
// HKTB=HKT[B]
|
||||
func ChainFirst[A, B, HKTA, HKTB any](
|
||||
mchain func(HKTA, func(A) HKTA) HKTA,
|
||||
mmap func(HKTB, func(B) A) HKTA,
|
||||
mchain func(func(A) HKTA) func(HKTA) HKTA,
|
||||
mmap func(func(B) A) func(HKTB) HKTA,
|
||||
f func(A) HKTB) func(HKTA) HKTA {
|
||||
return F.Bind2nd(mchain, func(a A) HKTA {
|
||||
return mmap(f(a), F.Constant1[B](a))
|
||||
return mchain(func(a A) HKTA {
|
||||
return mmap(F.Constant1[B](a))(f(a))
|
||||
})
|
||||
}
|
||||
|
||||
func Chain[A, B, HKTA, HKTB any](
|
||||
mchain func(HKTA, func(A) HKTB) HKTB,
|
||||
mchain func(func(A) HKTB) func(HKTA) HKTB,
|
||||
f func(A) HKTB,
|
||||
) func(HKTA) HKTB {
|
||||
return func(first HKTA) HKTB {
|
||||
return MonadChain[A, B](mchain, first, f)
|
||||
}
|
||||
return mchain(f)
|
||||
}
|
||||
|
||||
func MonadBind[S1, S2, B, HKTS1, HKTS2, HKTB any](
|
||||
mchain func(HKTS1, func(S1) HKTS2) HKTS2,
|
||||
mmap func(HKTB, func(B) S2) HKTS2,
|
||||
first HKTS1,
|
||||
key func(B) func(S1) S2,
|
||||
f func(S1) HKTB,
|
||||
) HKTS2 {
|
||||
return mchain(first, func(s1 S1) HKTS2 {
|
||||
return mmap(f(s1), func(b B) S2 {
|
||||
return key(b)(s1)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func Bind[S1, S2, B, HKTS1, HKTS2, HKTB any](
|
||||
mchain func(func(S1) HKTS2) func(HKTS1) HKTS2,
|
||||
mmap func(func(B) S2) func(HKTB) HKTS2,
|
||||
key func(B) func(S1) S2,
|
||||
f func(S1) HKTB,
|
||||
) func(HKTS1) HKTS2 {
|
||||
mapb := F.Flow2(
|
||||
F.Flip(key),
|
||||
mmap,
|
||||
)
|
||||
return mchain(func(s1 S1) HKTS2 {
|
||||
return F.Pipe2(
|
||||
s1,
|
||||
f,
|
||||
F.Pipe1(
|
||||
s1,
|
||||
mapb,
|
||||
),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
func BindTo[S1, B, HKTS1, HKTB any](
|
||||
mmap func(func(B) S1) func(HKTB) HKTS1,
|
||||
key func(B) S1,
|
||||
) func(fa HKTB) HKTS1 {
|
||||
return mmap(key)
|
||||
}
|
||||
|
||||
func MonadBindTo[S1, B, HKTS1, HKTB any](
|
||||
mmap func(HKTB, func(B) S1) HKTS1,
|
||||
first HKTB,
|
||||
key func(B) S1,
|
||||
) HKTS1 {
|
||||
return mmap(first, key)
|
||||
}
|
||||
|
@@ -20,17 +20,22 @@ import (
|
||||
|
||||
E "github.com/IBM/fp-go/eq"
|
||||
F "github.com/IBM/fp-go/function"
|
||||
"github.com/IBM/fp-go/internal/apply"
|
||||
L "github.com/IBM/fp-go/internal/apply/testing"
|
||||
"github.com/IBM/fp-go/internal/chain"
|
||||
"github.com/IBM/fp-go/internal/functor"
|
||||
"github.com/IBM/fp-go/internal/pointed"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// Chain associativity law
|
||||
//
|
||||
// F.chain(F.chain(fa, afb), bfc) <-> F.chain(fa, a => F.chain(afb(a), bfc))
|
||||
//
|
||||
// Deprecated: use [ChainAssertAssociativity] instead
|
||||
func AssertAssociativity[HKTA, HKTB, HKTC, A, B, C any](t *testing.T,
|
||||
eq E.Eq[HKTC],
|
||||
|
||||
fofa func(A) HKTA,
|
||||
fofb func(B) HKTB,
|
||||
fofc func(C) HKTC,
|
||||
|
||||
@@ -56,12 +61,44 @@ func AssertAssociativity[HKTA, HKTB, HKTC, A, B, C any](t *testing.T,
|
||||
}
|
||||
}
|
||||
|
||||
// Chain associativity law
|
||||
//
|
||||
// F.chain(F.chain(fa, afb), bfc) <-> F.chain(fa, a => F.chain(afb(a), bfc))
|
||||
func ChainAssertAssociativity[HKTA, HKTB, HKTC, HKTAB, HKTAC, HKTBC, A, B, C any](t *testing.T,
|
||||
eq E.Eq[HKTC],
|
||||
|
||||
fofb pointed.Pointed[B, HKTB],
|
||||
fofc pointed.Pointed[C, HKTC],
|
||||
|
||||
chainab chain.Chainable[A, B, HKTA, HKTB, HKTAB],
|
||||
chainac chain.Chainable[A, C, HKTA, HKTC, HKTAC],
|
||||
chainbc chain.Chainable[B, C, HKTB, HKTC, HKTBC],
|
||||
|
||||
ab func(A) B,
|
||||
bc func(B) C,
|
||||
) func(fa HKTA) bool {
|
||||
return func(fa HKTA) bool {
|
||||
|
||||
afb := F.Flow2(ab, fofb.Of)
|
||||
bfc := F.Flow2(bc, fofc.Of)
|
||||
|
||||
left := chainbc.Chain(bfc)(chainab.Chain(afb)(fa))
|
||||
|
||||
right := chainac.Chain(func(a A) HKTC {
|
||||
return chainbc.Chain(bfc)(afb(a))
|
||||
})(fa)
|
||||
|
||||
return assert.True(t, eq.Equals(left, right), "Chain associativity")
|
||||
}
|
||||
}
|
||||
|
||||
// AssertLaws asserts the apply laws `identity`, `composition`, `associative composition` and `associativity`
|
||||
//
|
||||
// Deprecated: use [ChainAssertLaws] instead
|
||||
func AssertLaws[HKTA, HKTB, HKTC, HKTAB, HKTBC, HKTAC, HKTABAC, A, B, C any](t *testing.T,
|
||||
eqa E.Eq[HKTA],
|
||||
eqc E.Eq[HKTC],
|
||||
|
||||
fofa func(A) HKTA,
|
||||
fofb func(B) HKTB,
|
||||
fofc func(C) HKTC,
|
||||
|
||||
@@ -91,7 +128,41 @@ func AssertLaws[HKTA, HKTB, HKTC, HKTAB, HKTBC, HKTAC, HKTABAC, A, B, C any](t *
|
||||
// apply laws
|
||||
apply := L.AssertLaws(t, eqa, eqc, fofab, fofbc, faa, fab, fac, fbc, fmap, fapab, fapbc, fapac, fapabac, ab, bc)
|
||||
// chain laws
|
||||
associativity := AssertAssociativity(t, eqc, fofa, fofb, fofc, chainab, chainac, chainbc, ab, bc)
|
||||
associativity := AssertAssociativity(t, eqc, fofb, fofc, chainab, chainac, chainbc, ab, bc)
|
||||
|
||||
return func(fa HKTA) bool {
|
||||
return apply(fa) && associativity(fa)
|
||||
}
|
||||
}
|
||||
|
||||
// ChainAssertLaws asserts the apply laws `identity`, `composition`, `associative composition` and `associativity`
|
||||
func ChainAssertLaws[HKTA, HKTB, HKTC, HKTAB, HKTBC, HKTAC, HKTABAC, A, B, C any](t *testing.T,
|
||||
eqa E.Eq[HKTA],
|
||||
eqc E.Eq[HKTC],
|
||||
|
||||
fofb pointed.Pointed[B, HKTB],
|
||||
fofc pointed.Pointed[C, HKTC],
|
||||
|
||||
fofab pointed.Pointed[func(A) B, HKTAB],
|
||||
fofbc pointed.Pointed[func(B) C, HKTBC],
|
||||
|
||||
faa functor.Functor[A, A, HKTA, HKTA],
|
||||
|
||||
fmap functor.Functor[func(B) C, func(func(A) B) func(A) C, HKTBC, HKTABAC],
|
||||
|
||||
chainab chain.Chainable[A, B, HKTA, HKTB, HKTAB],
|
||||
chainac chain.Chainable[A, C, HKTA, HKTC, HKTAC],
|
||||
chainbc chain.Chainable[B, C, HKTB, HKTC, HKTBC],
|
||||
|
||||
fapabac apply.Apply[func(A) B, func(A) C, HKTAB, HKTAC, HKTABAC],
|
||||
|
||||
ab func(A) B,
|
||||
bc func(B) C,
|
||||
) func(fa HKTA) bool {
|
||||
// apply laws
|
||||
apply := L.ApplyAssertLaws(t, eqa, eqc, fofab, fofbc, faa, fmap, chain.ToApply(chainab), chain.ToApply(chainbc), chain.ToApply(chainac), fapabac, ab, bc)
|
||||
// chain laws
|
||||
associativity := ChainAssertAssociativity(t, eqc, fofb, fofc, chainab, chainac, chainbc, ab, bc)
|
||||
|
||||
return func(fa HKTA) bool {
|
||||
return apply(fa) && associativity(fa)
|
||||
|
36
internal/chain/types.go
Normal file
36
internal/chain/types.go
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2024 IBM Corp.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package chain
|
||||
|
||||
import (
|
||||
"github.com/IBM/fp-go/internal/apply"
|
||||
"github.com/IBM/fp-go/internal/functor"
|
||||
)
|
||||
|
||||
type Chainable[A, B, HKTA, HKTB, HKTFAB any] interface {
|
||||
apply.Apply[A, B, HKTA, HKTB, HKTFAB]
|
||||
Chain(func(A) HKTB) func(HKTA) HKTB
|
||||
}
|
||||
|
||||
// ToFunctor converts from [Chainable] to [functor.Functor]
|
||||
func ToFunctor[A, B, HKTA, HKTB, HKTFAB any](ap Chainable[A, B, HKTA, HKTB, HKTFAB]) functor.Functor[A, B, HKTA, HKTB] {
|
||||
return ap
|
||||
}
|
||||
|
||||
// ToApply converts from [Chainable] to [functor.Functor]
|
||||
func ToApply[A, B, HKTA, HKTB, HKTFAB any](ap Chainable[A, B, HKTA, HKTB, HKTFAB]) apply.Apply[A, B, HKTA, HKTB, HKTFAB] {
|
||||
return ap
|
||||
}
|
@@ -51,6 +51,14 @@ func MonadMap[E, A, B, HKTFA, HKTFB any](fmap func(HKTFA, func(ET.Either[E, A])
|
||||
return FC.MonadMap(fmap, ET.MonadMap[E, A, B], fa, f)
|
||||
}
|
||||
|
||||
func Map[E, A, B, HKTFA, HKTFB any](
|
||||
fmap func(func(ET.Either[E, A]) ET.Either[E, B]) func(HKTFA) HKTFB,
|
||||
f func(A) B) func(HKTFA) HKTFB {
|
||||
// HKTGA = Either[E, A]
|
||||
// HKTGB = Either[E, B]
|
||||
return FC.Map(fmap, ET.Map[E, A, B], f)
|
||||
}
|
||||
|
||||
// HKTFA = HKT<F, Either<E, A>>
|
||||
// HKTFB = HKT<F, Either<E, B>>
|
||||
func MonadBiMap[E1, E2, A, B, HKTFA, HKTFB any](fmap func(HKTFA, func(ET.Either[E1, A]) ET.Either[E2, B]) HKTFB, fa HKTFA, f func(E1) E2, g func(A) B) HKTFB {
|
||||
@@ -61,10 +69,12 @@ func MonadBiMap[E1, E2, A, B, HKTFA, HKTFB any](fmap func(HKTFA, func(ET.Either[
|
||||
|
||||
// HKTFA = HKT<F, Either<E, A>>
|
||||
// HKTFB = HKT<F, Either<E, B>>
|
||||
func BiMap[E1, E2, A, B, HKTFA, HKTFB any](fmap func(HKTFA, func(ET.Either[E1, A]) ET.Either[E2, B]) HKTFB, f func(E1) E2, g func(A) B) func(HKTFA) HKTFB {
|
||||
func BiMap[E1, E2, A, B, HKTFA, HKTFB any](
|
||||
fmap func(func(ET.Either[E1, A]) ET.Either[E2, B]) func(HKTFA) HKTFB,
|
||||
f func(E1) E2, g func(A) B) func(HKTFA) HKTFB {
|
||||
// HKTGA = Either[E, A]
|
||||
// HKTGB = Either[E, B]
|
||||
return F.Bind2nd(fmap, ET.BiMap(f, g))
|
||||
return fmap(ET.BiMap(f, g))
|
||||
}
|
||||
|
||||
// HKTFA = HKT<F, Either<E, A>>
|
||||
@@ -78,22 +88,29 @@ func MonadChain[E, A, B, HKTFA, HKTFB any](
|
||||
return fchain(ma, ET.Fold(F.Flow2(ET.Left[B, E], fof), f))
|
||||
}
|
||||
|
||||
// func(fa func(R) T.Task[ET.Either[E, func(A) B]], f func(ET.Either[E, func(A) B]) func(ET.Either[E, A]) ET.Either[E, B]) GEFAB
|
||||
func Chain[E, A, B, HKTFA, HKTFB any](
|
||||
fchain func(func(ET.Either[E, A]) HKTFB) func(HKTFA) HKTFB,
|
||||
fof func(ET.Either[E, B]) HKTFB,
|
||||
f func(A) HKTFB) func(HKTFA) HKTFB {
|
||||
// dispatch to the even more generic implementation
|
||||
return fchain(ET.Fold(F.Flow2(ET.Left[B, E], fof), f))
|
||||
}
|
||||
|
||||
// HKTFA = HKT[Either[E, A]]
|
||||
// HKTFB = HKT[Either[E, B]]
|
||||
// HKTFAB = HKT[Either[E, func(A)B]]
|
||||
func MonadAp[E, A, B, HKTFAB, HKTFGAB, HKTFA, HKTFB any](
|
||||
fap func(HKTFGAB, HKTFA) HKTFB,
|
||||
fmap func(HKTFAB, func(ET.Either[E, func(A) B]) func(ET.Either[E, A]) ET.Either[E, B]) HKTFGAB,
|
||||
fab HKTFAB,
|
||||
fa HKTFA) HKTFB {
|
||||
// HKTGA = ET.Either[E, A]
|
||||
// HKTGB = ET.Either[E, B]
|
||||
// HKTGAB = ET.Either[E, func(a A) B]
|
||||
return apply.MonadAp(fap, fmap, ET.MonadAp[B, E, A], fab, fa)
|
||||
}
|
||||
|
||||
func Ap[E, A, B, HKTFAB, HKTFGAB, HKTFA, HKTFB any](
|
||||
fap func(HKTFA) func(HKTFGAB) HKTFB,
|
||||
fmap func(func(ET.Either[E, func(A) B]) func(ET.Either[E, A]) ET.Either[E, B]) func(HKTFAB) HKTFGAB,
|
||||
fa HKTFA) func(HKTFAB) HKTFB {
|
||||
return apply.Ap(fap, fmap, ET.Ap[B, E, A], fa)
|
||||
}
|
||||
|
||||
func Right[E, A, HKTA any](fof func(ET.Either[E, A]) HKTA, a A) HKTA {
|
||||
return F.Pipe2(a, ET.Right[E, A], fof)
|
||||
}
|
||||
@@ -142,3 +159,7 @@ func OrLeft[E1, E2, A, HKTE1A, HKTE2, HKTE2A any](
|
||||
func MonadMapLeft[E, A, B, HKTFA, HKTFB any](fmap func(HKTFA, func(ET.Either[E, A]) ET.Either[B, A]) HKTFB, fa HKTFA, f func(E) B) HKTFB {
|
||||
return FC.MonadMap(fmap, ET.MonadMapLeft[E, A, B], fa, f)
|
||||
}
|
||||
|
||||
func MapLeft[E, A, B, HKTFA, HKTFB any](fmap func(func(ET.Either[E, A]) ET.Either[B, A]) func(HKTFA) HKTFB, f func(E) B) func(HKTFA) HKTFB {
|
||||
return FC.Map(fmap, ET.MapLeft[A, E, B], f)
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@ import (
|
||||
|
||||
EX "github.com/IBM/fp-go/exec"
|
||||
|
||||
T "github.com/IBM/fp-go/tuple"
|
||||
P "github.com/IBM/fp-go/pair"
|
||||
)
|
||||
|
||||
func Exec(ctx context.Context, name string, args []string, in []byte) (EX.CommandOutput, error) {
|
||||
@@ -42,5 +42,5 @@ func Exec(ctx context.Context, name string, args []string, in []byte) (EX.Comman
|
||||
err = fmt.Errorf("command execution of [%s][%s] failed, stdout [%s], stderr [%s], cause [%w]", name, args, stdOut.String(), stdErr.String(), err)
|
||||
}
|
||||
// return the outputs
|
||||
return T.MakeTuple2(stdOut.Bytes(), stdErr.Bytes()), err
|
||||
return P.MakePair(stdOut.Bytes(), stdErr.Bytes()), err
|
||||
}
|
||||
|
26
internal/foldable/types.go
Normal file
26
internal/foldable/types.go
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2024 IBM Corp.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package foldable
|
||||
|
||||
import (
|
||||
M "github.com/IBM/fp-go/monoid"
|
||||
)
|
||||
|
||||
type Foldable[A, B, HKTA any] interface {
|
||||
Reduce(func(B, A) B, B) func(HKTA) B
|
||||
ReduceRight(func(B, A) B, B) func(HKTA) B
|
||||
FoldMap(m M.Monoid[B]) func(func(A) B) func(HKTA) B
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user