mirror of
https://github.com/IBM/fp-go.git
synced 2025-08-26 19:38:58 +02:00
Compare commits
166 Commits
cleue-http
...
v1.0.75
Author | SHA1 | Date | |
---|---|---|---|
|
5fcd0b1595 | ||
|
5caabf478c | ||
|
b7ec18c83e | ||
|
96686425fb | ||
|
1f675e08fa | ||
|
4d2f410c98 | ||
|
8f49c1328c | ||
|
2a1d5821db | ||
|
6abbdc5ee1 | ||
|
5fea9858a9 | ||
|
e6426c90c0 | ||
|
54ce59105e | ||
|
8bb006c741 | ||
|
b6efa35b03 | ||
|
35848900c0 | ||
|
3d54f99739 | ||
|
ffd9418cac | ||
|
acfcea59f4 | ||
|
b4bf511f03 | ||
|
211340952b | ||
|
56860425c4 | ||
|
c0b16c675b | ||
|
4b68e66528 | ||
|
5b7e5b153b | ||
|
d43fbeb375 | ||
|
57d507c1ba | ||
|
aa19857127 | ||
|
7766787cc1 | ||
|
6a9f38f990 | ||
|
e9584bc247 | ||
|
55252c5680 | ||
|
88bf35c4af | ||
|
da3c9683eb | ||
|
08d9fed9af | ||
|
83a0c6cdef | ||
|
9da484b79e | ||
|
e46cfd89d4 | ||
|
6a4cdfa891 | ||
|
93a7e9964b | ||
|
9ef98e1ec4 | ||
|
f1a730998d | ||
|
f129297045 | ||
|
b434f1fbf4 | ||
|
756e1336dc | ||
|
c629d18bb3 | ||
|
1eefc28ba6 | ||
|
af2915d98a | ||
|
e9f9c2777f | ||
|
895862a67e | ||
|
caf0574742 | ||
|
bace6f01eb | ||
|
254c63a16f | ||
|
655c8a9b1d | ||
|
c6d6be66e0 | ||
|
e313f95865 | ||
|
5f25317f97 | ||
|
f5aa2d6c15 | ||
|
7262820624 | ||
|
c8fc10358b | ||
|
1cd167541d | ||
|
ebe94d71dc | ||
|
7ef6eb524b | ||
|
7b82e87bf3 | ||
|
e8fdbe9f87 | ||
|
226c7039de | ||
|
943ae8e009 | ||
|
44c8441b07 | ||
|
600aeae770 | ||
|
f74a407294 | ||
|
b15ab38861 | ||
|
6532a83e82 | ||
|
7c12b72db1 | ||
|
dc894ad643 | ||
|
c902058320 | ||
|
bf33f4fb66 | ||
|
b4d2a5c6be | ||
|
705b71d95c | ||
|
34844bcfc2 | ||
|
9a9d13b066 | ||
|
da1449e680 | ||
|
865d9fe064 | ||
|
c5b1bae65a | ||
|
0a395f63ff | ||
|
26a7066de0 | ||
|
52823e2c8e | ||
|
503021c65e | ||
|
a2a6a41993 | ||
|
7da9de6f41 | ||
|
ff1b6faf84 | ||
|
38120764e7 | ||
|
a83c2aec49 | ||
|
03debd37c8 | ||
|
4f04344cda | ||
|
cf1c886f48 | ||
|
3e0eb99b88 | ||
|
cb15a3d9fc | ||
|
16535605f5 | ||
|
53f4e5ebd7 | ||
|
fb91fd5dc8 | ||
|
3ccafb5302 | ||
|
52b71ef4f3 | ||
|
5d77d5bb3d | ||
|
8ba8f852fa | ||
|
29d9882d2a | ||
|
f80ca31e14 | ||
|
8692078972 | ||
|
12a4f6801c | ||
|
8650a8a600 | ||
|
fb3b1f115c | ||
|
ce66cf2295 | ||
|
80e579dd0b | ||
|
ddafd1ee57 | ||
|
b5f077da71 | ||
|
1a0c40b419 | ||
|
d5d89b1853 | ||
|
0f061a5099 | ||
|
45e05f25ff | ||
|
a390d53451 | ||
|
1346b9378a | ||
|
befd4f471e | ||
|
db8d3da87a | ||
|
ee4e936183 | ||
|
0064ac1c75 | ||
|
8944a66c18 | ||
|
bd0c42db01 | ||
|
e9f03e2d26 | ||
|
bb630810fc | ||
|
9ba9eaacbe | ||
|
a9f6839acd | ||
|
1b1dccc551 | ||
|
39c6108bf5 | ||
|
83e1ff30c1 | ||
|
d9dda4cfa5 | ||
|
d9b2804a7e | ||
|
c0028918ae | ||
|
cd53cb7036 | ||
|
469c60f05d | ||
|
74fd0c96e7 | ||
|
e53e2c53e8 | ||
|
2cd35870cb | ||
|
411caa6dff | ||
|
d69a13ecf4 | ||
|
4ed0046971 | ||
|
e4fd34a6b5 | ||
|
89265eed7c | ||
|
fbc6757f82 | ||
|
a12936a86c | ||
|
94bcfde0d3 | ||
|
4e1cb825e7 | ||
|
9988ae27ef | ||
|
903669c1bc | ||
|
dc836fd0be | ||
|
47a6d3c177 | ||
|
d2346b016e | ||
|
41b792b23a | ||
|
1713de0c3e | ||
|
8c58e8d760 | ||
|
7476b70a23 | ||
|
9e14cd1c00 | ||
|
205b728bda | ||
|
7817f3c676 | ||
|
811f966553 | ||
|
91d7961363 | ||
|
ff7d750d97 | ||
|
9e32acf551 | ||
|
680c103239 |
19
.github/workflows/build.yml
vendored
19
.github/workflows/build.yml
vendored
@@ -17,22 +17,25 @@ on:
|
|||||||
env:
|
env:
|
||||||
# Currently no way to detect automatically
|
# Currently no way to detect automatically
|
||||||
DEFAULT_BRANCH: main
|
DEFAULT_BRANCH: main
|
||||||
GO_VERSION: 1.20.5 # renovate: datasource=golang-version depName=golang
|
GO_VERSION: 1.20.6 # renovate: datasource=golang-version depName=golang
|
||||||
NODE_VERSION: 18
|
NODE_VERSION: 18
|
||||||
DRY_RUN: true
|
DRY_RUN: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
go-version: [ '1.20.x', '1.21.x' ]
|
||||||
steps:
|
steps:
|
||||||
# full checkout for semantic-release
|
# full checkout for semantic-release
|
||||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Set up go ${{env.GO_VERSION}}
|
- name: Set up go ${{ matrix.go-version }}
|
||||||
uses: actions/setup-go@v4
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ${{env.GO_VERSION}}
|
go-version: ${{ matrix.go-version }}
|
||||||
-
|
-
|
||||||
name: Tests
|
name: Tests
|
||||||
run: |
|
run: |
|
||||||
@@ -52,17 +55,17 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
# full checkout for semantic-release
|
# full checkout for semantic-release
|
||||||
- name: Full checkout
|
- name: Full checkout
|
||||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Set up Node.js ${{ env.NODE_VERSION }}
|
- name: Set up Node.js ${{ env.NODE_VERSION }}
|
||||||
uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
node-version: ${{ env.NODE_VERSION }}
|
node-version: ${{ env.NODE_VERSION }}
|
||||||
|
|
||||||
- name: Set up go ${{env.GO_VERSION}}
|
- name: Set up go ${{env.GO_VERSION}}
|
||||||
uses: actions/setup-go@v4
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ${{env.GO_VERSION}}
|
go-version: ${{env.GO_VERSION}}
|
||||||
|
|
||||||
|
55
README.md
55
README.md
@@ -1,6 +1,6 @@
|
|||||||
# Functional programming library for golang
|
# Functional programming library for golang
|
||||||
|
|
||||||
**🚧 Work in progress! 🚧** Despite major version 1 because of https://github.com/semantic-release/semantic-release/issues/1507. Trying to not make breaking changes, but devil is in the details.
|
**🚧 Work in progress! 🚧** Despite major version 1 because of <https://github.com/semantic-release/semantic-release/issues/1507>. Trying to not make breaking changes, but devil is in the details.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -12,7 +12,9 @@ This library is strongly influenced by the awesome [fp-ts](https://github.com/gc
|
|||||||
go get github.com/IBM/fp-go
|
go get github.com/IBM/fp-go
|
||||||
```
|
```
|
||||||
|
|
||||||
Refer to the [samples](./samples/).
|
Refer to the [samples](./samples/).
|
||||||
|
|
||||||
|
Find API documentation [here](https://pkg.go.dev/github.com/IBM/fp-go)
|
||||||
|
|
||||||
## Design Goal
|
## Design Goal
|
||||||
|
|
||||||
@@ -65,7 +67,7 @@ This library aims to provide a set of data types and functions that make it easy
|
|||||||
|
|
||||||
#### 🧘🏽 Moderation is a virtue
|
#### 🧘🏽 Moderation is a virtue
|
||||||
|
|
||||||
✔️ The library does not implement its own goroutines and also does not require any expensive synchronization primitives. Coordination of IO operations is implemented via atomic counters without additional primitives.
|
✔️ The library does not implement its own goroutines and also does not require any expensive synchronization primitives. Coordination of IO operations is implemented via atomic counters without additional primitives.
|
||||||
|
|
||||||
#### 🧘🏽 Maintainability counts
|
#### 🧘🏽 Maintainability counts
|
||||||
|
|
||||||
@@ -73,6 +75,40 @@ This library aims to provide a set of data types and functions that make it easy
|
|||||||
|
|
||||||
The library itself also comprises many small functions, but it's admittedly harder to maintain than code that uses it. However this asymmetry is intended because it offloads complexity from users into a central component.
|
The library itself also comprises many small functions, but it's admittedly harder to maintain than code that uses it. However this asymmetry is intended because it offloads complexity from users into a central component.
|
||||||
|
|
||||||
|
## Comparison to Idiomatic Go
|
||||||
|
|
||||||
|
In this section we discuss how the functional APIs differ from idiomatic go function signatures and how to convert back and forth.
|
||||||
|
|
||||||
|
### Pure functions
|
||||||
|
|
||||||
|
Pure functions are functions that take input parameters and that compute an output without changing any global state and without mutating the input parameters. They will always return the same output for the same input.
|
||||||
|
|
||||||
|
#### Without Errors
|
||||||
|
|
||||||
|
If your pure function does not return an error, the idiomatic signature is just fine and no changes are required.
|
||||||
|
|
||||||
|
#### With Errors
|
||||||
|
|
||||||
|
If your pure function can return an error, then it will have a `(T, error)` return value in idiomatic go. In functional style the return value is [Either[error, T]](https://pkg.go.dev/github.com/IBM/fp-go/either) because function composition is easier with such a return type. Use the `EitherizeXXX` methods in ["github.com/IBM/fp-go/either"](https://pkg.go.dev/github.com/IBM/fp-go/either) to convert from idiomatic to functional style and `UneitherizeXXX` to convert from functional to idiomatic style.
|
||||||
|
|
||||||
|
### Effectful functions
|
||||||
|
|
||||||
|
An effectful function (or function with a side effect) is one that changes data outside the scope of the function or that does not always produce the same output for the same input (because it depends on some external, mutable state). There is no special way in idiomatic go to identify such a function other than documentation. In functional style we represent them as functions that do not take an input but that produce an output. The base type for these functions is [IO[T]](https://pkg.go.dev/github.com/IBM/fp-go/io) because in many cases such functions represent `I/O` operations.
|
||||||
|
|
||||||
|
#### Without Errors
|
||||||
|
|
||||||
|
If your effectful function does not return an error, the functional signature is [IO[T]](https://pkg.go.dev/github.com/IBM/fp-go/io)
|
||||||
|
|
||||||
|
#### With Errors
|
||||||
|
|
||||||
|
If your effectful function can return an error, the functional signature is [IOEither[error, T]](https://pkg.go.dev/github.com/IBM/fp-go/ioeither). Use `EitherizeXXX` from ["github.com/IBM/fp-go/ioeither"](https://pkg.go.dev/github.com/IBM/fp-go/ioeither) to convert an idiomatic go function to functional style.
|
||||||
|
|
||||||
|
### Go Context
|
||||||
|
|
||||||
|
Functions that take a [context](https://pkg.go.dev/context) are per definition effectful because they depend on the context parameter that is designed to be mutable (it can e.g. be used to cancel a running operation). Furthermore in idiomatic go the parameter is typically passed as the first parameter to a function.
|
||||||
|
|
||||||
|
In functional style we isolate the [context](https://pkg.go.dev/context) and represent the nature of the effectful function as an [IOEither[error, T]](https://pkg.go.dev/github.com/IBM/fp-go/ioeither). The resulting type is [ReaderIOEither[T]](https://pkg.go.dev/github.com/IBM/fp-go/context/readerioeither), a function taking a [context](https://pkg.go.dev/context) that returns a function without parameters returning an [Either[error, T]](https://pkg.go.dev/github.com/IBM/fp-go/either). Use the `EitherizeXXX` methods from ["github.com/IBM/fp-go/context/readerioeither"](https://pkg.go.dev/github.com/IBM/fp-go/context/readerioeither) to convert an idiomatic go function with a [context](https://pkg.go.dev/context) to functional style.
|
||||||
|
|
||||||
## Implementation Notes
|
## Implementation Notes
|
||||||
|
|
||||||
### Generics
|
### Generics
|
||||||
@@ -147,7 +183,7 @@ The `Map` operation for `ReaderIOEither` is defined as:
|
|||||||
func Map[R, E, A, B any](f func(A) B) func(fa ReaderIOEither[R, E, A]) ReaderIOEither[R, E, B]
|
func Map[R, E, A, B any](f func(A) B) func(fa ReaderIOEither[R, E, A]) ReaderIOEither[R, E, B]
|
||||||
```
|
```
|
||||||
|
|
||||||
and in fact the equivalent operations for all other mondas follow the same pattern, we could try to introduce a new type for `ReaderIOEither` (without a parameter) as a HKT, e.g. like so (made-up syntax, does not work in go):
|
and in fact the equivalent operations for all other monads follow the same pattern, we could try to introduce a new type for `ReaderIOEither` (without a parameter) as a HKT, e.g. like so (made-up syntax, does not work in go):
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func Map[HKT, R, E, A, B any](f func(A) B) func(HKT[R, E, A]) HKT[R, E, B]
|
func Map[HKT, R, E, A, B any](f func(A) B) func(HKT[R, E, A]) HKT[R, E, B]
|
||||||
@@ -158,3 +194,14 @@ this would be the completely generic method signature for all possible monads. I
|
|||||||
This FP library addresses this by introducing the HKTs as individual types, e.g. `HKT[A]` would be represented as a new generic type `HKTA`. This loses the correlation to the type `A` but allows to implement generic algorithms, at the price of readability.
|
This FP library addresses this by introducing the HKTs as individual types, e.g. `HKT[A]` would be represented as a new generic type `HKTA`. This loses the correlation to the type `A` but allows to implement generic algorithms, at the price of readability.
|
||||||
|
|
||||||
For that reason these implementations are kept in the `internal` package. These are meant to be used by the library itself or by extensions, not by end users.
|
For that reason these implementations are kept in the `internal` package. These are meant to be used by the library itself or by extensions, not by end users.
|
||||||
|
|
||||||
|
## Map/Ap/Flap
|
||||||
|
|
||||||
|
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]` |
|
||||||
|
30
array/any.go
Normal file
30
array/any.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 array
|
||||||
|
|
||||||
|
import (
|
||||||
|
G "github.com/IBM/fp-go/array/generic"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AnyWithIndex tests if any of the elements in the array matches the predicate
|
||||||
|
func AnyWithIndex[A any](pred func(int, A) bool) func([]A) bool {
|
||||||
|
return G.AnyWithIndex[[]A](pred)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any tests if any of the elements in the array matches the predicate
|
||||||
|
func Any[A any](pred func(A) bool) func([]A) bool {
|
||||||
|
return G.Any[[]A](pred)
|
||||||
|
}
|
30
array/any_test.go
Normal file
30
array/any_test.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 array
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
F "github.com/IBM/fp-go/function"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAny(t *testing.T) {
|
||||||
|
anyBool := Any(F.Identity[bool])
|
||||||
|
|
||||||
|
assert.True(t, anyBool(From(false, true, false)))
|
||||||
|
assert.False(t, anyBool(From(false, false, false)))
|
||||||
|
}
|
159
array/array.go
159
array/array.go
@@ -1,3 +1,18 @@
|
|||||||
|
// 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
|
package array
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -15,22 +30,13 @@ func From[A any](data ...A) []A {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MakeBy returns a `Array` of length `n` with element `i` initialized with `f(i)`.
|
// MakeBy returns a `Array` of length `n` with element `i` initialized with `f(i)`.
|
||||||
func MakeBy[A any](n int, f func(int) A) []A {
|
func MakeBy[F ~func(int) A, A any](n int, f F) []A {
|
||||||
// sanity check
|
return G.MakeBy[[]A](n, f)
|
||||||
if n <= 0 {
|
|
||||||
return Empty[A]()
|
|
||||||
}
|
|
||||||
// run the generator function across the input
|
|
||||||
as := make([]A, n)
|
|
||||||
for i := n - 1; i >= 0; i-- {
|
|
||||||
as[i] = f(i)
|
|
||||||
}
|
|
||||||
return as
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replicate creates a `Array` containing a value repeated the specified number of times.
|
// Replicate creates a `Array` containing a value repeated the specified number of times.
|
||||||
func Replicate[A any](n int, a A) []A {
|
func Replicate[A any](n int, a A) []A {
|
||||||
return MakeBy(n, F.Constant1[int](a))
|
return G.Replicate[[]A](n, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
func MonadMap[A, B any](as []A, f func(a A) B) []B {
|
func MonadMap[A, B any](as []A, f func(a A) B) []B {
|
||||||
@@ -46,6 +52,10 @@ func MonadMapRef[A, B any](as []A, f func(a *A) B) []B {
|
|||||||
return bs
|
return bs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MapWithIndex[A, B any](f func(int, A) B) func([]A) []B {
|
||||||
|
return G.MapWithIndex[[]A, []B](f)
|
||||||
|
}
|
||||||
|
|
||||||
func Map[A, B any](f func(a 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 F.Bind2nd(MonadMap[A, B], f)
|
||||||
}
|
}
|
||||||
@@ -54,18 +64,6 @@ func MapRef[A, B any](f func(a *A) B) func([]A) []B {
|
|||||||
return F.Bind2nd(MonadMapRef[A, B], f)
|
return F.Bind2nd(MonadMapRef[A, B], f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func filter[A any](fa []A, pred func(A) bool) []A {
|
|
||||||
var result []A
|
|
||||||
count := len(fa)
|
|
||||||
for i := 0; i < count; i++ {
|
|
||||||
a := fa[i]
|
|
||||||
if pred(a) {
|
|
||||||
result = append(result, a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func filterRef[A any](fa []A, pred func(a *A) bool) []A {
|
func filterRef[A any](fa []A, pred func(a *A) bool) []A {
|
||||||
var result []A
|
var result []A
|
||||||
count := len(fa)
|
count := len(fa)
|
||||||
@@ -90,22 +88,43 @@ func filterMapRef[A, B any](fa []A, pred func(a *A) bool, f func(a *A) B) []B {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Filter returns a new array with all elements from the original array that match a predicate
|
||||||
func Filter[A any](pred func(A) bool) func([]A) []A {
|
func Filter[A any](pred func(A) bool) func([]A) []A {
|
||||||
return F.Bind2nd(filter[A], pred)
|
return G.Filter[[]A](pred)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterWithIndex returns a new array with all elements from the original array that match a predicate
|
||||||
|
func FilterWithIndex[A any](pred func(int, A) bool) func([]A) []A {
|
||||||
|
return G.FilterWithIndex[[]A](pred)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FilterRef[A any](pred func(*A) bool) func([]A) []A {
|
func FilterRef[A any](pred func(*A) bool) func([]A) []A {
|
||||||
return F.Bind2nd(filterRef[A], pred)
|
return F.Bind2nd(filterRef[A], pred)
|
||||||
}
|
}
|
||||||
|
|
||||||
func MonadFilterMap[A, B any](fa []A, f func(a A) O.Option[B]) []B {
|
func MonadFilterMap[A, B any](fa []A, f func(A) O.Option[B]) []B {
|
||||||
return G.MonadFilterMap[[]A, []B](fa, f)
|
return G.MonadFilterMap[[]A, []B](fa, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FilterMap[A, B any](f func(a A) O.Option[B]) func([]A) []B {
|
func MonadFilterMapWithIndex[A, B any](fa []A, f func(int, A) O.Option[B]) []B {
|
||||||
|
return G.MonadFilterMapWithIndex[[]A, []B](fa, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterMap maps an array with an iterating function that returns an [O.Option] and it keeps only the Some values discarding the Nones.
|
||||||
|
func FilterMap[A, B any](f func(A) O.Option[B]) func([]A) []B {
|
||||||
return G.FilterMap[[]A, []B](f)
|
return G.FilterMap[[]A, []B](f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FilterMapWithIndex maps an array with an iterating function that returns an [O.Option] and it keeps only the Some values discarding the Nones.
|
||||||
|
func FilterMapWithIndex[A, B any](f func(int, A) O.Option[B]) func([]A) []B {
|
||||||
|
return G.FilterMapWithIndex[[]A, []B](f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterChain maps an array with an iterating function that returns an [O.Option] of an array. It keeps only the Some values discarding the Nones and then flattens the result.
|
||||||
|
func FilterChain[A, B any](f func(A) O.Option[[]B]) func([]A) []B {
|
||||||
|
return G.FilterChain[[]A](f)
|
||||||
|
}
|
||||||
|
|
||||||
func FilterMapRef[A, B any](pred func(a *A) bool, f func(a *A) B) func([]A) []B {
|
func FilterMapRef[A, B any](pred func(a *A) bool, f func(a *A) B) func([]A) []B {
|
||||||
return func(fa []A) []B {
|
return func(fa []A) []B {
|
||||||
return filterMapRef(fa, pred, f)
|
return filterMapRef(fa, pred, f)
|
||||||
@@ -122,9 +141,19 @@ func reduceRef[A, B any](fa []A, f func(B, *A) B, initial B) B {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Reduce[A, B any](f func(B, A) B, initial B) func([]A) B {
|
func Reduce[A, B any](f func(B, A) B, initial B) func([]A) B {
|
||||||
return func(as []A) B {
|
return G.Reduce[[]A](f, initial)
|
||||||
return array.Reduce(as, f, initial)
|
}
|
||||||
}
|
|
||||||
|
func ReduceWithIndex[A, B any](f func(int, B, A) B, initial B) func([]A) B {
|
||||||
|
return G.ReduceWithIndex[[]A](f, initial)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReduceRight[A, B any](f func(A, B) B, initial B) func([]A) B {
|
||||||
|
return G.ReduceRight[[]A](f, initial)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReduceRightWithIndex[A, B any](f func(int, A, B) B, initial B) func([]A) B {
|
||||||
|
return G.ReduceRightWithIndex[[]A](f, initial)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReduceRef[A, B any](f func(B, *A) B, initial B) func([]A) B {
|
func ReduceRef[A, B any](f func(B, *A) B, initial B) func([]A) B {
|
||||||
@@ -138,7 +167,7 @@ func Append[A any](as []A, a A) []A {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func IsEmpty[A any](as []A) bool {
|
func IsEmpty[A any](as []A) bool {
|
||||||
return array.IsEmpty(as)
|
return G.IsEmpty(as)
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsNonEmpty[A any](as []A) bool {
|
func IsNonEmpty[A any](as []A) bool {
|
||||||
@@ -159,30 +188,27 @@ func Of[A any](a A) []A {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func MonadChain[A, B any](fa []A, f func(a A) []B) []B {
|
func MonadChain[A, B any](fa []A, f func(a A) []B) []B {
|
||||||
return array.Reduce(fa, func(bs []B, a A) []B {
|
return G.MonadChain[[]A, []B](fa, f)
|
||||||
return append(bs, f(a)...)
|
|
||||||
}, Zero[B]())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Chain[A, B any](f func(a A) []B) func([]A) []B {
|
func Chain[A, B any](f func(A) []B) func([]A) []B {
|
||||||
return F.Bind2nd(MonadChain[A, B], f)
|
return G.Chain[[]A, []B](f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func MonadAp[B, A any](fab []func(A) B, fa []A) []B {
|
func MonadAp[B, A any](fab []func(A) B, fa []A) []B {
|
||||||
return MonadChain(fab, F.Bind1st(MonadMap[A, B], fa))
|
return G.MonadAp[[]B](fab, fa)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Ap[B, A any](fa []A) func([]func(A) B) []B {
|
func Ap[B, A any](fa []A) func([]func(A) B) []B {
|
||||||
return F.Bind2nd(MonadAp[B, A], fa)
|
return G.Ap[[]B, []func(A) B](fa)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Match[A, B any](onEmpty func() B, onNonEmpty func([]A) B) func([]A) B {
|
func Match[A, B any](onEmpty func() B, onNonEmpty func([]A) B) func([]A) B {
|
||||||
return func(as []A) B {
|
return G.Match[[]A](onEmpty, onNonEmpty)
|
||||||
if IsEmpty(as) {
|
}
|
||||||
return onEmpty()
|
|
||||||
}
|
func MatchLeft[A, B any](onEmpty func() B, onNonEmpty func(A, []A) B) func([]A) B {
|
||||||
return onNonEmpty(as)
|
return G.MatchLeft[[]A](onEmpty, onNonEmpty)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Tail[A any](as []A) O.Option[[]A] {
|
func Tail[A any](as []A) O.Option[[]A] {
|
||||||
@@ -227,14 +253,14 @@ func Intersperse[A any](middle A) func([]A) []A {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Intercalate[A any](m M.Monoid[A]) func(A) func([]A) A {
|
func Intercalate[A any](m M.Monoid[A]) func(A) func([]A) A {
|
||||||
concatAll := ConcatAll[A](m)(m.Empty())
|
concatAll := ConcatAll[A](m)
|
||||||
return func(middle A) func([]A) A {
|
return func(middle A) func([]A) A {
|
||||||
return Match(m.Empty, F.Flow2(Intersperse(middle), concatAll))
|
return Match(m.Empty, F.Flow2(Intersperse(middle), concatAll))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Flatten[A any](mma [][]A) []A {
|
func Flatten[A any](mma [][]A) []A {
|
||||||
return MonadChain(mma, F.Identity[[]A])
|
return G.Flatten(mma)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Slice[A any](low, high int) func(as []A) []A {
|
func Slice[A any](low, high int) func(as []A) []A {
|
||||||
@@ -277,3 +303,44 @@ func IsNonNil[A any](as []A) bool {
|
|||||||
func ConstNil[A any]() []A {
|
func ConstNil[A any]() []A {
|
||||||
return array.ConstNil[[]A]()
|
return array.ConstNil[[]A]()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SliceRight[A any](start int) func([]A) []A {
|
||||||
|
return G.SliceRight[[]A](start)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy creates a shallow copy of the array
|
||||||
|
func Copy[A any](b []A) []A {
|
||||||
|
return G.Copy(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone creates a deep copy of the array using the provided endomorphism to clone the values
|
||||||
|
func Clone[A any](f func(A) A) func(as []A) []A {
|
||||||
|
return G.Clone[[]A](f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FoldMap maps and folds an array. Map the Array passing each value to the iterating function. Then fold the results using the provided Monoid.
|
||||||
|
func FoldMap[A, B any](m M.Monoid[B]) func(func(A) B) func([]A) B {
|
||||||
|
return G.FoldMap[[]A](m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FoldMapWithIndex maps and folds an array. Map the Array passing each value to the iterating function. Then fold the results using the provided Monoid.
|
||||||
|
func FoldMapWithIndex[A, B any](m M.Monoid[B]) func(func(int, A) B) func([]A) B {
|
||||||
|
return G.FoldMapWithIndex[[]A](m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fold folds the array using the provided Monoid.
|
||||||
|
func Fold[A any](m M.Monoid[A]) func([]A) A {
|
||||||
|
return G.Fold[[]A](m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Push[A any](a A) func([]A) []A {
|
||||||
|
return G.Push[[]A](a)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MonadFlap[B, A any](fab []func(A) B, a A) []B {
|
||||||
|
return G.MonadFlap[func(A) B, []func(A) B, []B, A, B](fab, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Flap[B, A any](a A) func([]func(A) B) []B {
|
||||||
|
return G.Flap[func(A) B, []func(A) B, []B, A, B](a)
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,22 @@
|
|||||||
|
// 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
|
package array
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -43,6 +59,17 @@ func TestMap(t *testing.T) {
|
|||||||
assert.Equal(t, dst, []string{"A", "B", "C"})
|
assert.Equal(t, dst, []string{"A", "B", "C"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReduceRight(t *testing.T) {
|
||||||
|
values := From("a", "b", "c")
|
||||||
|
f := func(a, acc string) string {
|
||||||
|
return fmt.Sprintf("%s%s", acc, a)
|
||||||
|
}
|
||||||
|
b := ""
|
||||||
|
|
||||||
|
assert.Equal(t, "cba", ReduceRight(f, b)(values))
|
||||||
|
assert.Equal(t, "", ReduceRight(f, b)(Empty[string]()))
|
||||||
|
}
|
||||||
|
|
||||||
func TestReduce(t *testing.T) {
|
func TestReduce(t *testing.T) {
|
||||||
|
|
||||||
values := MakeBy(101, F.Identity[int])
|
values := MakeBy(101, F.Identity[int])
|
||||||
@@ -127,3 +154,52 @@ func TestPartition(t *testing.T) {
|
|||||||
assert.Equal(t, T.MakeTuple2(Empty[int](), Empty[int]()), Partition(pred)(Empty[int]()))
|
assert.Equal(t, T.MakeTuple2(Empty[int](), Empty[int]()), Partition(pred)(Empty[int]()))
|
||||||
assert.Equal(t, T.MakeTuple2(From(1), From(3)), Partition(pred)(From(1, 3)))
|
assert.Equal(t, T.MakeTuple2(From(1), From(3)), Partition(pred)(From(1, 3)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFilterChain(t *testing.T) {
|
||||||
|
src := From(1, 2, 3)
|
||||||
|
|
||||||
|
f := func(i int) O.Option[[]string] {
|
||||||
|
if i%2 != 0 {
|
||||||
|
return O.Of(From(fmt.Sprintf("a%d", i), fmt.Sprintf("b%d", i)))
|
||||||
|
}
|
||||||
|
return O.None[[]string]()
|
||||||
|
}
|
||||||
|
|
||||||
|
res := FilterChain(f)(src)
|
||||||
|
|
||||||
|
assert.Equal(t, From("a1", "b1", "a3", "b3"), res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilterMap(t *testing.T) {
|
||||||
|
src := From(1, 2, 3)
|
||||||
|
|
||||||
|
f := func(i int) O.Option[string] {
|
||||||
|
if i%2 != 0 {
|
||||||
|
return O.Of(fmt.Sprintf("a%d", i))
|
||||||
|
}
|
||||||
|
return O.None[string]()
|
||||||
|
}
|
||||||
|
|
||||||
|
res := FilterMap(f)(src)
|
||||||
|
|
||||||
|
assert.Equal(t, From("a1", "a3"), res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFoldMap(t *testing.T) {
|
||||||
|
src := From("a", "b", "c")
|
||||||
|
|
||||||
|
fold := FoldMap[string](S.Monoid)(strings.ToUpper)
|
||||||
|
|
||||||
|
assert.Equal(t, "ABC", fold(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleFoldMap() {
|
||||||
|
src := From("a", "b", "c")
|
||||||
|
|
||||||
|
fold := FoldMap[string](S.Monoid)(strings.ToUpper)
|
||||||
|
|
||||||
|
fmt.Println(fold(src))
|
||||||
|
|
||||||
|
// Output: ABC
|
||||||
|
|
||||||
|
}
|
||||||
|
15
array/eq.go
15
array/eq.go
@@ -1,3 +1,18 @@
|
|||||||
|
// 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
|
package array
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
77
array/example_any_test.go
Normal file
77
array/example_any_test.go
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
// 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 (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
F "github.com/IBM/fp-go/function"
|
||||||
|
O "github.com/IBM/fp-go/option"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Example_any() {
|
||||||
|
|
||||||
|
pred := func(val int) bool {
|
||||||
|
return val&2 == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
data1 := From(1, 2, 3)
|
||||||
|
|
||||||
|
fmt.Println(Any(pred)(data1))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
}
|
||||||
|
|
||||||
|
func Example_any_filter() {
|
||||||
|
|
||||||
|
pred := func(val int) bool {
|
||||||
|
return val&2 == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
data1 := From(1, 2, 3)
|
||||||
|
|
||||||
|
// Any tests if any of the entries in the array matches the condition
|
||||||
|
Any := F.Flow2(
|
||||||
|
Filter(pred),
|
||||||
|
IsNonEmpty[int],
|
||||||
|
)
|
||||||
|
|
||||||
|
fmt.Println(Any(data1))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
}
|
||||||
|
|
||||||
|
func Example_any_find() {
|
||||||
|
|
||||||
|
pred := func(val int) bool {
|
||||||
|
return val&2 == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
data1 := From(1, 2, 3)
|
||||||
|
|
||||||
|
// Any tests if any of the entries in the array matches the condition
|
||||||
|
Any := F.Flow2(
|
||||||
|
FindFirst(pred),
|
||||||
|
O.IsSome[int],
|
||||||
|
)
|
||||||
|
|
||||||
|
fmt.Println(Any(data1))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
}
|
55
array/example_find_test.go
Normal file
55
array/example_find_test.go
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
// 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 (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
F "github.com/IBM/fp-go/function"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Example_find() {
|
||||||
|
|
||||||
|
pred := func(val int) bool {
|
||||||
|
return val&2 == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
data1 := From(1, 2, 3)
|
||||||
|
|
||||||
|
fmt.Println(FindFirst(pred)(data1))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Some[int](1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Example_find_filter() {
|
||||||
|
|
||||||
|
pred := func(val int) bool {
|
||||||
|
return val&2 == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
data1 := From(1, 2, 3)
|
||||||
|
|
||||||
|
Find := F.Flow2(
|
||||||
|
Filter(pred),
|
||||||
|
Head[int],
|
||||||
|
)
|
||||||
|
|
||||||
|
fmt.Println(Find(data1))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Some[int](1)
|
||||||
|
}
|
59
array/examples_basic_test.go
Normal file
59
array/examples_basic_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 array
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
F "github.com/IBM/fp-go/function"
|
||||||
|
O "github.com/IBM/fp-go/option"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Example_basic adapts examples from [https://github.com/inato/fp-ts-cheatsheet#basic-manipulation]
|
||||||
|
func Example_basic() {
|
||||||
|
|
||||||
|
someArray := From(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) // []int
|
||||||
|
|
||||||
|
isEven := func(num int) bool {
|
||||||
|
return num%2 == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
square := func(num int) int {
|
||||||
|
return num * num
|
||||||
|
}
|
||||||
|
|
||||||
|
// filter and map
|
||||||
|
result := F.Pipe2(
|
||||||
|
someArray,
|
||||||
|
Filter(isEven),
|
||||||
|
Map(square),
|
||||||
|
) // [0 4 16 36 64]
|
||||||
|
|
||||||
|
// or in one go with filterMap
|
||||||
|
resultFilterMap := F.Pipe1(
|
||||||
|
someArray,
|
||||||
|
FilterMap(
|
||||||
|
F.Flow2(O.FromPredicate(isEven), O.Map(square)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
fmt.Println(result)
|
||||||
|
fmt.Println(resultFilterMap)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [0 4 16 36 64]
|
||||||
|
// [0 4 16 36 64]
|
||||||
|
}
|
92
array/examples_sort_test.go
Normal file
92
array/examples_sort_test.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 array
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
F "github.com/IBM/fp-go/function"
|
||||||
|
I "github.com/IBM/fp-go/number/integer"
|
||||||
|
O "github.com/IBM/fp-go/option"
|
||||||
|
"github.com/IBM/fp-go/ord"
|
||||||
|
S "github.com/IBM/fp-go/string"
|
||||||
|
)
|
||||||
|
|
||||||
|
type user struct {
|
||||||
|
name string
|
||||||
|
age O.Option[int]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (user user) GetName() string {
|
||||||
|
return user.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (user user) GetAge() O.Option[int] {
|
||||||
|
return user.age
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example_sort adapts examples from [https://github.com/inato/fp-ts-cheatsheet#sort-elements-with-ord]
|
||||||
|
func Example_sort() {
|
||||||
|
|
||||||
|
strings := From("zyx", "abc", "klm")
|
||||||
|
|
||||||
|
sortedStrings := F.Pipe1(
|
||||||
|
strings,
|
||||||
|
Sort(S.Ord),
|
||||||
|
) // => ['abc', 'klm', 'zyx']
|
||||||
|
|
||||||
|
// reverse sort
|
||||||
|
reverseSortedStrings := F.Pipe1(
|
||||||
|
strings,
|
||||||
|
Sort(ord.Reverse(S.Ord)),
|
||||||
|
) // => ['zyx', 'klm', 'abc']
|
||||||
|
|
||||||
|
// sort Option
|
||||||
|
optionalNumbers := From(O.Some(1337), O.None[int](), O.Some(42))
|
||||||
|
|
||||||
|
sortedNums := F.Pipe1(
|
||||||
|
optionalNumbers,
|
||||||
|
Sort(O.Ord(I.Ord)),
|
||||||
|
)
|
||||||
|
|
||||||
|
// complex object with different rules
|
||||||
|
byName := F.Pipe1(
|
||||||
|
S.Ord,
|
||||||
|
ord.Contramap(user.GetName),
|
||||||
|
) // ord.Ord[user]
|
||||||
|
|
||||||
|
byAge := F.Pipe1(
|
||||||
|
O.Ord(I.Ord),
|
||||||
|
ord.Contramap(user.GetAge),
|
||||||
|
) // ord.Ord[user]
|
||||||
|
|
||||||
|
sortedUsers := F.Pipe1(
|
||||||
|
From(user{name: "a", age: O.Of(30)}, user{name: "d", age: O.Of(10)}, user{name: "c"}, user{name: "b", age: O.Of(10)}),
|
||||||
|
SortBy(From(byAge, byName)),
|
||||||
|
)
|
||||||
|
|
||||||
|
fmt.Println(sortedStrings)
|
||||||
|
fmt.Println(reverseSortedStrings)
|
||||||
|
fmt.Println(sortedNums)
|
||||||
|
fmt.Println(sortedUsers)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// [abc klm zyx]
|
||||||
|
// [zyx klm abc]
|
||||||
|
// [None[int] Some[int](42) Some[int](1337)]
|
||||||
|
// [{c {false 0}} {b {true 10}} {d {true 10}} {a {true 30}}]
|
||||||
|
|
||||||
|
}
|
61
array/find.go
Normal file
61
array/find.go
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
// 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"
|
||||||
|
O "github.com/IBM/fp-go/option"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FindFirst finds the first element which satisfies a predicate (or a refinement) function
|
||||||
|
func FindFirst[A any](pred func(A) bool) func([]A) O.Option[A] {
|
||||||
|
return G.FindFirst[[]A](pred)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindFirstWithIndex finds the first element which satisfies a predicate (or a refinement) function
|
||||||
|
func FindFirstWithIndex[A any](pred func(int, A) bool) func([]A) O.Option[A] {
|
||||||
|
return G.FindFirstWithIndex[[]A](pred)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindFirstMap finds the first element returned by an [O.Option] based selector function
|
||||||
|
func FindFirstMap[A, B any](sel func(A) O.Option[B]) func([]A) O.Option[B] {
|
||||||
|
return G.FindFirstMap[[]A](sel)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindFirstMapWithIndex finds the first element returned by an [O.Option] based selector function
|
||||||
|
func FindFirstMapWithIndex[A, B any](sel func(int, A) O.Option[B]) func([]A) O.Option[B] {
|
||||||
|
return G.FindFirstMapWithIndex[[]A](sel)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindLast finds the Last element which satisfies a predicate (or a refinement) function
|
||||||
|
func FindLast[A any](pred func(A) bool) func([]A) O.Option[A] {
|
||||||
|
return G.FindLast[[]A](pred)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindLastWithIndex finds the Last element which satisfies a predicate (or a refinement) function
|
||||||
|
func FindLastWithIndex[A any](pred func(int, A) bool) func([]A) O.Option[A] {
|
||||||
|
return G.FindLastWithIndex[[]A](pred)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindLastMap finds the Last element returned by an [O.Option] based selector function
|
||||||
|
func FindLastMap[A, B any](sel func(A) O.Option[B]) func([]A) O.Option[B] {
|
||||||
|
return G.FindLastMap[[]A](sel)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindLastMapWithIndex finds the Last element returned by an [O.Option] based selector function
|
||||||
|
func FindLastMapWithIndex[A, B any](sel func(int, A) O.Option[B]) func([]A) O.Option[B] {
|
||||||
|
return G.FindLastMapWithIndex[[]A](sel)
|
||||||
|
}
|
34
array/generic/any.go
Normal file
34
array/generic/any.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
// 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 (
|
||||||
|
F "github.com/IBM/fp-go/function"
|
||||||
|
O "github.com/IBM/fp-go/option"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AnyWithIndex tests if any of the elements in the array matches the predicate
|
||||||
|
func AnyWithIndex[AS ~[]A, PRED ~func(int, A) bool, A any](pred PRED) func(AS) bool {
|
||||||
|
return F.Flow2(
|
||||||
|
FindFirstWithIndex[AS](pred),
|
||||||
|
O.IsSome[A],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any tests if any of the elements in the array matches the predicate
|
||||||
|
func Any[AS ~[]A, PRED ~func(A) bool, A any](pred PRED) func(AS) bool {
|
||||||
|
return AnyWithIndex[AS](F.Ignore1of2[int](pred))
|
||||||
|
}
|
@@ -1,8 +1,25 @@
|
|||||||
|
// 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
|
package generic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
F "github.com/IBM/fp-go/function"
|
F "github.com/IBM/fp-go/function"
|
||||||
"github.com/IBM/fp-go/internal/array"
|
"github.com/IBM/fp-go/internal/array"
|
||||||
|
FC "github.com/IBM/fp-go/internal/functor"
|
||||||
|
M "github.com/IBM/fp-go/monoid"
|
||||||
O "github.com/IBM/fp-go/option"
|
O "github.com/IBM/fp-go/option"
|
||||||
"github.com/IBM/fp-go/tuple"
|
"github.com/IBM/fp-go/tuple"
|
||||||
)
|
)
|
||||||
@@ -12,11 +29,69 @@ func Of[GA ~[]A, A any](value A) GA {
|
|||||||
return GA{value}
|
return GA{value}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Reduce[GA ~[]A, A, B any](f func(B, A) B, initial B) func(GA) B {
|
||||||
|
return func(as GA) B {
|
||||||
|
return MonadReduce[GA](as, f, initial)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReduceWithIndex[GA ~[]A, A, B any](f func(int, B, A) B, initial B) func(GA) B {
|
||||||
|
return func(as GA) B {
|
||||||
|
return MonadReduceWithIndex[GA](as, f, initial)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReduceRight[GA ~[]A, A, B any](f func(A, B) B, initial B) func(GA) B {
|
||||||
|
return func(as GA) B {
|
||||||
|
return MonadReduceRight[GA](as, f, initial)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReduceRightWithIndex[GA ~[]A, A, B any](f func(int, A, B) B, initial B) func(GA) B {
|
||||||
|
return func(as GA) B {
|
||||||
|
return MonadReduceRightWithIndex[GA](as, f, initial)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func MonadReduce[GA ~[]A, A, B any](fa GA, f func(B, A) B, initial B) B {
|
||||||
|
return array.Reduce(fa, f, initial)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MonadReduceWithIndex[GA ~[]A, A, B any](fa GA, f func(int, B, A) B, initial B) B {
|
||||||
|
return array.ReduceWithIndex(fa, f, initial)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MonadReduceRight[GA ~[]A, A, B any](fa GA, f func(A, B) B, initial B) B {
|
||||||
|
return array.ReduceRight(fa, f, initial)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MonadReduceRightWithIndex[GA ~[]A, A, B any](fa GA, f func(int, A, B) B, initial B) B {
|
||||||
|
return array.ReduceRightWithIndex(fa, f, initial)
|
||||||
|
}
|
||||||
|
|
||||||
// From constructs an array from a set of variadic arguments
|
// From constructs an array from a set of variadic arguments
|
||||||
func From[GA ~[]A, A any](data ...A) GA {
|
func From[GA ~[]A, A any](data ...A) GA {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MakeBy returns a `Array` of length `n` with element `i` initialized with `f(i)`.
|
||||||
|
func MakeBy[AS ~[]A, F ~func(int) A, A any](n int, f F) AS {
|
||||||
|
// sanity check
|
||||||
|
if n <= 0 {
|
||||||
|
return Empty[AS]()
|
||||||
|
}
|
||||||
|
// run the generator function across the input
|
||||||
|
as := make(AS, n)
|
||||||
|
for i := n - 1; i >= 0; i-- {
|
||||||
|
as[i] = f(i)
|
||||||
|
}
|
||||||
|
return as
|
||||||
|
}
|
||||||
|
|
||||||
|
func Replicate[AS ~[]A, A any](n int, a A) AS {
|
||||||
|
return MakeBy[AS](n, F.Constant1[int](a))
|
||||||
|
}
|
||||||
|
|
||||||
func Lookup[GA ~[]A, A any](idx int) func(GA) O.Option[A] {
|
func Lookup[GA ~[]A, A any](idx int) func(GA) O.Option[A] {
|
||||||
none := O.None[A]()
|
none := O.None[A]()
|
||||||
if idx < 0 {
|
if idx < 0 {
|
||||||
@@ -71,24 +146,79 @@ func MonadMap[GA ~[]A, GB ~[]B, A, B any](as GA, f func(a A) B) GB {
|
|||||||
return array.MonadMap[GA, GB](as, f)
|
return array.MonadMap[GA, GB](as, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MonadMapWithIndex[GA ~[]A, GB ~[]B, A, B any](as GA, f func(int, A) B) GB {
|
||||||
|
return array.MonadMapWithIndex[GA, GB](as, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MapWithIndex[GA ~[]A, GB ~[]B, A, B any](f func(int, A) B) func(GA) GB {
|
||||||
|
return F.Bind2nd(MonadMapWithIndex[GA, GB, A, B], f)
|
||||||
|
}
|
||||||
|
|
||||||
func Size[GA ~[]A, A any](as GA) int {
|
func Size[GA ~[]A, A any](as GA) int {
|
||||||
return len(as)
|
return len(as)
|
||||||
}
|
}
|
||||||
|
|
||||||
func filterMap[GA ~[]A, GB ~[]B, A, B any](fa GA, f func(a A) O.Option[B]) GB {
|
func filterMap[GA ~[]A, GB ~[]B, A, B any](fa GA, f func(A) O.Option[B]) GB {
|
||||||
return array.Reduce(fa, func(bs GB, a A) GB {
|
return array.Reduce(fa, func(bs GB, a A) GB {
|
||||||
return O.MonadFold(f(a), F.Constant(bs), F.Bind1st(Append[GB, B], bs))
|
return O.MonadFold(f(a), F.Constant(bs), F.Bind1st(Append[GB, B], bs))
|
||||||
}, Empty[GB]())
|
}, Empty[GB]())
|
||||||
}
|
}
|
||||||
|
|
||||||
func MonadFilterMap[GA ~[]A, GB ~[]B, A, B any](fa GA, f func(a A) O.Option[B]) GB {
|
func filterMapWithIndex[GA ~[]A, GB ~[]B, A, B any](fa GA, f func(int, A) O.Option[B]) GB {
|
||||||
|
return array.ReduceWithIndex(fa, func(idx int, bs GB, a A) GB {
|
||||||
|
return O.MonadFold(f(idx, a), F.Constant(bs), F.Bind1st(Append[GB, B], bs))
|
||||||
|
}, Empty[GB]())
|
||||||
|
}
|
||||||
|
|
||||||
|
func MonadFilterMap[GA ~[]A, GB ~[]B, A, B any](fa GA, f func(A) O.Option[B]) GB {
|
||||||
return filterMap[GA, GB](fa, f)
|
return filterMap[GA, GB](fa, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FilterMap[GA ~[]A, GB ~[]B, A, B any](f func(a A) O.Option[B]) func(GA) GB {
|
func MonadFilterMapWithIndex[GA ~[]A, GB ~[]B, A, B any](fa GA, f func(int, A) O.Option[B]) GB {
|
||||||
|
return filterMapWithIndex[GA, GB](fa, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func filterWithIndex[AS ~[]A, PRED ~func(int, A) bool, A any](fa AS, pred PRED) AS {
|
||||||
|
result := make(AS, 0, len(fa))
|
||||||
|
for i, a := range fa {
|
||||||
|
if pred(i, a) {
|
||||||
|
result = append(result, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func FilterWithIndex[AS ~[]A, PRED ~func(int, A) bool, A any](pred PRED) func(AS) AS {
|
||||||
|
return F.Bind2nd(filterWithIndex[AS, PRED, A], pred)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Filter[AS ~[]A, PRED ~func(A) bool, A any](pred PRED) func(AS) AS {
|
||||||
|
return FilterWithIndex[AS](F.Ignore1of2[int](pred))
|
||||||
|
}
|
||||||
|
|
||||||
|
func FilterChain[GA ~[]A, GB ~[]B, A, B any](f func(a A) O.Option[GB]) func(GA) GB {
|
||||||
|
return F.Flow2(
|
||||||
|
FilterMap[GA, []GB](f),
|
||||||
|
Flatten[[]GB],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Flatten[GAA ~[]GA, GA ~[]A, A any](mma GAA) GA {
|
||||||
|
return MonadChain(mma, F.Identity[GA])
|
||||||
|
}
|
||||||
|
|
||||||
|
func FilterMap[GA ~[]A, GB ~[]B, A, B any](f func(A) O.Option[B]) func(GA) GB {
|
||||||
return F.Bind2nd(MonadFilterMap[GA, GB, A, B], f)
|
return F.Bind2nd(MonadFilterMap[GA, GB, A, B], f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FilterMapWithIndex[GA ~[]A, GB ~[]B, A, B any](f func(int, A) O.Option[B]) func(GA) GB {
|
||||||
|
return F.Bind2nd(MonadFilterMapWithIndex[GA, GB, A, B], f)
|
||||||
|
}
|
||||||
|
|
||||||
func MonadPartition[GA ~[]A, A any](as GA, pred func(A) bool) tuple.Tuple2[GA, GA] {
|
func MonadPartition[GA ~[]A, A any](as GA, pred func(A) bool) tuple.Tuple2[GA, GA] {
|
||||||
left := Empty[GA]()
|
left := Empty[GA]()
|
||||||
right := Empty[GA]()
|
right := Empty[GA]()
|
||||||
@@ -107,3 +237,112 @@ func MonadPartition[GA ~[]A, A any](as GA, pred func(A) bool) tuple.Tuple2[GA, G
|
|||||||
func Partition[GA ~[]A, A any](pred func(A) bool) func(GA) tuple.Tuple2[GA, GA] {
|
func Partition[GA ~[]A, A any](pred func(A) bool) func(GA) tuple.Tuple2[GA, GA] {
|
||||||
return F.Bind2nd(MonadPartition[GA, A], pred)
|
return F.Bind2nd(MonadPartition[GA, A], pred)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MonadChain[AS ~[]A, BS ~[]B, A, B any](fa AS, f func(a A) BS) BS {
|
||||||
|
return array.Reduce(fa, func(bs BS, a A) BS {
|
||||||
|
return append(bs, f(a)...)
|
||||||
|
}, Empty[BS]())
|
||||||
|
}
|
||||||
|
|
||||||
|
func Chain[AS ~[]A, BS ~[]B, A, B any](f func(A) BS) func(AS) BS {
|
||||||
|
return F.Bind2nd(MonadChain[AS, BS, A, B], f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MonadAp[BS ~[]B, ABS ~[]func(A) B, AS ~[]A, B, A any](fab ABS, fa AS) BS {
|
||||||
|
return MonadChain(fab, F.Bind1st(MonadMap[AS, BS, A, B], fa))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Ap[BS ~[]B, ABS ~[]func(A) B, AS ~[]A, B, A any](fa AS) func(ABS) BS {
|
||||||
|
return F.Bind2nd(MonadAp[BS, ABS, AS], fa)
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsEmpty[AS ~[]A, A any](as AS) bool {
|
||||||
|
return array.IsEmpty(as)
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsNil[GA ~[]A, A any](as GA) bool {
|
||||||
|
return array.IsNil(as)
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsNonNil[GA ~[]A, A any](as GA) bool {
|
||||||
|
return array.IsNonNil(as)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Match[AS ~[]A, A, B any](onEmpty func() B, onNonEmpty func(AS) B) func(AS) B {
|
||||||
|
return func(as AS) B {
|
||||||
|
if IsEmpty(as) {
|
||||||
|
return onEmpty()
|
||||||
|
}
|
||||||
|
return onNonEmpty(as)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func MatchLeft[AS ~[]A, A, B any](onEmpty func() B, onNonEmpty func(A, AS) B) func(AS) B {
|
||||||
|
return func(as AS) B {
|
||||||
|
if IsEmpty(as) {
|
||||||
|
return onEmpty()
|
||||||
|
}
|
||||||
|
return onNonEmpty(as[0], as[1:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Slice[AS ~[]A, A any](start int, end int) func(AS) AS {
|
||||||
|
return func(a AS) AS {
|
||||||
|
return a[start:end]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SliceRight[AS ~[]A, A any](start int) func(AS) AS {
|
||||||
|
return func(a AS) AS {
|
||||||
|
return a[start:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Copy[AS ~[]A, A any](b AS) AS {
|
||||||
|
buf := make(AS, len(b))
|
||||||
|
copy(buf, b)
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|
||||||
|
func Clone[AS ~[]A, A any](f func(A) A) func(as AS) AS {
|
||||||
|
// implementation assumes that map does not optimize for the empty array
|
||||||
|
return Map[AS, AS](f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func FoldMap[AS ~[]A, A, B any](m M.Monoid[B]) func(func(A) B) func(AS) B {
|
||||||
|
return func(f func(A) B) func(AS) B {
|
||||||
|
return func(as AS) B {
|
||||||
|
return array.Reduce(as, func(cur B, a A) B {
|
||||||
|
return m.Concat(cur, f(a))
|
||||||
|
}, m.Empty())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func FoldMapWithIndex[AS ~[]A, A, B any](m M.Monoid[B]) func(func(int, A) B) func(AS) B {
|
||||||
|
return func(f func(int, A) B) func(AS) B {
|
||||||
|
return func(as AS) B {
|
||||||
|
return array.ReduceWithIndex(as, func(idx int, cur B, a A) B {
|
||||||
|
return m.Concat(cur, f(idx, a))
|
||||||
|
}, m.Empty())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fold[AS ~[]A, A any](m M.Monoid[A]) func(AS) A {
|
||||||
|
return func(as AS) A {
|
||||||
|
return array.Reduce(as, m.Concat, m.Empty())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Push[GA ~[]A, A any](a A) func(GA) GA {
|
||||||
|
return F.Bind2nd(array.Push[GA, A], a)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MonadFlap[FAB ~func(A) B, GFAB ~[]FAB, GB ~[]B, A, B any](fab GFAB, a A) GB {
|
||||||
|
return FC.MonadFlap(MonadMap[GFAB, GB], fab, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
97
array/generic/find.go
Normal file
97
array/generic/find.go
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
// 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 (
|
||||||
|
F "github.com/IBM/fp-go/function"
|
||||||
|
O "github.com/IBM/fp-go/option"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FindFirstWithIndex finds the first element which satisfies a predicate (or a refinement) function
|
||||||
|
func FindFirstWithIndex[AS ~[]A, PRED ~func(int, A) bool, A any](pred PRED) func(AS) O.Option[A] {
|
||||||
|
none := O.None[A]()
|
||||||
|
return func(as AS) O.Option[A] {
|
||||||
|
for i, a := range as {
|
||||||
|
if pred(i, a) {
|
||||||
|
return O.Some(a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return none
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindFirst finds the first element which satisfies a predicate (or a refinement) function
|
||||||
|
func FindFirst[AS ~[]A, PRED ~func(A) bool, A any](pred PRED) func(AS) O.Option[A] {
|
||||||
|
return FindFirstWithIndex[AS](F.Ignore1of2[int](pred))
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindFirstMapWithIndex finds the first element returned by an [O.Option] based selector function
|
||||||
|
func FindFirstMapWithIndex[AS ~[]A, PRED ~func(int, A) O.Option[B], A, B any](pred PRED) func(AS) O.Option[B] {
|
||||||
|
none := O.None[B]()
|
||||||
|
return func(as AS) O.Option[B] {
|
||||||
|
count := len(as)
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
out := pred(i, as[i])
|
||||||
|
if O.IsSome(out) {
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return none
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindFirstMap finds the first element returned by an [O.Option] based selector function
|
||||||
|
func FindFirstMap[AS ~[]A, PRED ~func(A) O.Option[B], A, B any](pred PRED) func(AS) O.Option[B] {
|
||||||
|
return FindFirstMapWithIndex[AS](F.Ignore1of2[int](pred))
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindLastWithIndex finds the first element which satisfies a predicate (or a refinement) function
|
||||||
|
func FindLastWithIndex[AS ~[]A, PRED ~func(int, A) bool, A any](pred PRED) func(AS) O.Option[A] {
|
||||||
|
none := O.None[A]()
|
||||||
|
return func(as AS) O.Option[A] {
|
||||||
|
for i := len(as) - 1; i >= 0; i-- {
|
||||||
|
a := as[i]
|
||||||
|
if pred(i, a) {
|
||||||
|
return O.Some(a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return none
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindLast finds the first element which satisfies a predicate (or a refinement) function
|
||||||
|
func FindLast[AS ~[]A, PRED ~func(A) bool, A any](pred PRED) func(AS) O.Option[A] {
|
||||||
|
return FindLastWithIndex[AS](F.Ignore1of2[int](pred))
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindLastMapWithIndex finds the first element returned by an [O.Option] based selector function
|
||||||
|
func FindLastMapWithIndex[AS ~[]A, PRED ~func(int, A) O.Option[B], A, B any](pred PRED) func(AS) O.Option[B] {
|
||||||
|
none := O.None[B]()
|
||||||
|
return func(as AS) O.Option[B] {
|
||||||
|
for i := len(as) - 1; i >= 0; i-- {
|
||||||
|
out := pred(i, as[i])
|
||||||
|
if O.IsSome(out) {
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return none
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindLastMap finds the first element returned by an [O.Option] based selector function
|
||||||
|
func FindLastMap[AS ~[]A, PRED ~func(A) O.Option[B], A, B any](pred PRED) func(AS) O.Option[B] {
|
||||||
|
return FindLastMapWithIndex[AS](F.Ignore1of2[int](pred))
|
||||||
|
}
|
@@ -1,13 +1,34 @@
|
|||||||
|
// 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
|
package generic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
|
F "github.com/IBM/fp-go/function"
|
||||||
O "github.com/IBM/fp-go/ord"
|
O "github.com/IBM/fp-go/ord"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Sort implements a stable sort on the array given the provided ordering
|
// Sort implements a stable sort on the array given the provided ordering
|
||||||
func Sort[GA ~[]T, T any](ord O.Ord[T]) func(ma GA) GA {
|
func Sort[GA ~[]T, T any](ord O.Ord[T]) func(ma GA) GA {
|
||||||
|
return SortByKey[GA](ord, F.Identity[T])
|
||||||
|
}
|
||||||
|
|
||||||
|
// SortByKey implements a stable sort on the array given the provided ordering on an extracted key
|
||||||
|
func SortByKey[GA ~[]T, K, T any](ord O.Ord[K], f func(T) K) func(ma GA) GA {
|
||||||
|
|
||||||
return func(ma GA) GA {
|
return func(ma GA) GA {
|
||||||
// nothing to sort
|
// nothing to sort
|
||||||
@@ -19,8 +40,17 @@ func Sort[GA ~[]T, T any](ord O.Ord[T]) func(ma GA) GA {
|
|||||||
cpy := make(GA, l)
|
cpy := make(GA, l)
|
||||||
copy(cpy, ma)
|
copy(cpy, ma)
|
||||||
sort.Slice(cpy, func(i, j int) bool {
|
sort.Slice(cpy, func(i, j int) bool {
|
||||||
return ord.Compare(cpy[i], cpy[j]) < 0
|
return ord.Compare(f(cpy[i]), f(cpy[j])) < 0
|
||||||
})
|
})
|
||||||
return cpy
|
return cpy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SortBy implements a stable sort on the array given the provided ordering
|
||||||
|
func SortBy[GA ~[]T, GO ~[]O.Ord[T], T any](ord GO) func(ma GA) GA {
|
||||||
|
return F.Pipe2(
|
||||||
|
ord,
|
||||||
|
Fold[GO](O.Monoid[T]()),
|
||||||
|
Sort[GA, T],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
32
array/generic/uniq.go
Normal file
32
array/generic/uniq.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package generic
|
||||||
|
|
||||||
|
import F "github.com/IBM/fp-go/function"
|
||||||
|
|
||||||
|
// StrictUniq converts an array of arbitrary items into an array or unique items
|
||||||
|
// where uniqueness is determined by the built-in uniqueness constraint
|
||||||
|
func StrictUniq[AS ~[]A, A comparable](as AS) AS {
|
||||||
|
return Uniq[AS](F.Identity[A])(as)
|
||||||
|
}
|
||||||
|
|
||||||
|
// uniquePredUnsafe returns a predicate on a map for uniqueness
|
||||||
|
func uniquePredUnsafe[PRED ~func(A) K, A any, K comparable](f PRED) func(int, A) bool {
|
||||||
|
lookup := make(map[K]bool)
|
||||||
|
return func(_ int, a A) bool {
|
||||||
|
k := f(a)
|
||||||
|
_, has := lookup[k]
|
||||||
|
if has {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
lookup[k] = true
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uniq converts an array of arbitrary items into an array or unique items
|
||||||
|
// where uniqueness is determined based on a key extractor function
|
||||||
|
func Uniq[AS ~[]A, PRED ~func(A) K, A any, K comparable](f PRED) func(as AS) AS {
|
||||||
|
return func(as AS) AS {
|
||||||
|
// we need to create a new predicate for each iteration
|
||||||
|
return filterWithIndex(as, uniquePredUnsafe(f))
|
||||||
|
}
|
||||||
|
}
|
52
array/generic/zip.go
Normal file
52
array/generic/zip.go
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
// 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 (
|
||||||
|
F "github.com/IBM/fp-go/function"
|
||||||
|
N "github.com/IBM/fp-go/number"
|
||||||
|
T "github.com/IBM/fp-go/tuple"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ZipWith applies a function to pairs of elements at the same index in two arrays, collecting the results in a new array. If one
|
||||||
|
// input array is short, excess elements of the longer array are discarded.
|
||||||
|
func ZipWith[AS ~[]A, BS ~[]B, CS ~[]C, FCT ~func(A, B) C, A, B, C any](fa AS, fb BS, f FCT) CS {
|
||||||
|
l := N.Min(len(fa), len(fb))
|
||||||
|
res := make(CS, l)
|
||||||
|
for i := l - 1; i >= 0; i-- {
|
||||||
|
res[i] = f(fa[i], fb[i])
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zip takes two arrays and returns an array of corresponding pairs. If one input array is short, excess elements of the
|
||||||
|
// longer array are discarded
|
||||||
|
func Zip[AS ~[]A, BS ~[]B, CS ~[]T.Tuple2[A, B], A, B any](fb BS) func(AS) CS {
|
||||||
|
return F.Bind23of3(ZipWith[AS, BS, CS, func(A, B) T.Tuple2[A, B]])(fb, T.MakeTuple2[A, B])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unzip is the function is reverse of [Zip]. Takes an array of pairs and return two corresponding arrays
|
||||||
|
func Unzip[AS ~[]A, BS ~[]B, CS ~[]T.Tuple2[A, B], A, B any](cs CS) T.Tuple2[AS, BS] {
|
||||||
|
l := len(cs)
|
||||||
|
as := make(AS, l)
|
||||||
|
bs := make(BS, l)
|
||||||
|
for i := l - 1; i >= 0; i-- {
|
||||||
|
t := cs[i]
|
||||||
|
as[i] = t.F1
|
||||||
|
bs[i] = t.F2
|
||||||
|
}
|
||||||
|
return T.MakeTuple2(as, bs)
|
||||||
|
}
|
@@ -1,10 +1,24 @@
|
|||||||
|
// 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
|
package array
|
||||||
|
|
||||||
import (
|
import (
|
||||||
F "github.com/IBM/fp-go/function"
|
M "github.com/IBM/fp-go/monoid"
|
||||||
M "github.com/IBM/fp-go/magma"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func ConcatAll[A any](m M.Magma[A]) func(A) func([]A) A {
|
func ConcatAll[A any](m M.Monoid[A]) func([]A) A {
|
||||||
return F.Bind1st(Reduce[A, A], m.Concat)
|
return Reduce(m.Concat, m.Empty())
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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
|
package array
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -5,16 +20,16 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
M "github.com/IBM/fp-go/magma"
|
M "github.com/IBM/fp-go/monoid"
|
||||||
)
|
)
|
||||||
|
|
||||||
var subInt = M.MakeMagma(func(first int, second int) int {
|
var subInt = M.MakeMonoid(func(first int, second int) int {
|
||||||
return first - second
|
return first - second
|
||||||
})
|
}, 0)
|
||||||
|
|
||||||
func TestConcatAll(t *testing.T) {
|
func TestConcatAll(t *testing.T) {
|
||||||
|
|
||||||
var subAll = ConcatAll(subInt)(0)
|
var subAll = ConcatAll(subInt)
|
||||||
|
|
||||||
assert.Equal(t, subAll([]int{1, 2, 3}), -6)
|
assert.Equal(t, subAll([]int{1, 2, 3}), -6)
|
||||||
|
|
||||||
|
@@ -1,8 +1,24 @@
|
|||||||
|
// 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
|
package array
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/IBM/fp-go/internal/array"
|
"github.com/IBM/fp-go/internal/array"
|
||||||
M "github.com/IBM/fp-go/monoid"
|
M "github.com/IBM/fp-go/monoid"
|
||||||
|
S "github.com/IBM/fp-go/semigroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
func concat[T any](left, right []T) []T {
|
func concat[T any](left, right []T) []T {
|
||||||
@@ -25,6 +41,10 @@ func Monoid[T any]() M.Monoid[[]T] {
|
|||||||
return M.MakeMonoid(concat[T], Empty[T]())
|
return M.MakeMonoid(concat[T], Empty[T]())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Semigroup[T any]() S.Semigroup[[]T] {
|
||||||
|
return S.MakeSemigroup(concat[T])
|
||||||
|
}
|
||||||
|
|
||||||
func addLen[A any](count int, data []A) int {
|
func addLen[A any](count int, data []A) int {
|
||||||
return count + len(data)
|
return count + len(data)
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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
|
package array
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
124
array/nonempty/array.go
Normal file
124
array/nonempty/array.go
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
// 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 nonempty
|
||||||
|
|
||||||
|
import (
|
||||||
|
G "github.com/IBM/fp-go/array/generic"
|
||||||
|
F "github.com/IBM/fp-go/function"
|
||||||
|
"github.com/IBM/fp-go/internal/array"
|
||||||
|
S "github.com/IBM/fp-go/semigroup"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NonEmptyArray represents an array with at least one element
|
||||||
|
type NonEmptyArray[A any] []A
|
||||||
|
|
||||||
|
// Of constructs a single element array
|
||||||
|
func Of[A any](first A) NonEmptyArray[A] {
|
||||||
|
return G.Of[NonEmptyArray[A]](first)
|
||||||
|
}
|
||||||
|
|
||||||
|
// From constructs a [NonEmptyArray] from a set of variadic arguments
|
||||||
|
func From[A any](first A, data ...A) NonEmptyArray[A] {
|
||||||
|
count := len(data)
|
||||||
|
if count == 0 {
|
||||||
|
return Of(first)
|
||||||
|
}
|
||||||
|
// allocate the requested buffer
|
||||||
|
buffer := make(NonEmptyArray[A], count+1)
|
||||||
|
buffer[0] = first
|
||||||
|
copy(buffer[1:], data)
|
||||||
|
return buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsEmpty[A any](as NonEmptyArray[A]) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsNonEmpty[A any](as NonEmptyArray[A]) bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func MonadMap[A, B any](as NonEmptyArray[A], f func(a A) B) NonEmptyArray[B] {
|
||||||
|
return G.MonadMap[NonEmptyArray[A], NonEmptyArray[B]](as, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Map[A, B any](f func(a A) B) func(NonEmptyArray[A]) NonEmptyArray[B] {
|
||||||
|
return F.Bind2nd(MonadMap[A, B], f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Reduce[A, B any](f func(B, A) B, initial B) func(NonEmptyArray[A]) B {
|
||||||
|
return func(as NonEmptyArray[A]) B {
|
||||||
|
return array.Reduce(as, f, initial)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Tail[A any](as NonEmptyArray[A]) []A {
|
||||||
|
return as[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func Head[A any](as NonEmptyArray[A]) A {
|
||||||
|
return as[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func First[A any](as NonEmptyArray[A]) A {
|
||||||
|
return as[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func Last[A any](as NonEmptyArray[A]) A {
|
||||||
|
return as[len(as)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func Size[A any](as NonEmptyArray[A]) int {
|
||||||
|
return G.Size(as)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Flatten[A any](mma NonEmptyArray[NonEmptyArray[A]]) NonEmptyArray[A] {
|
||||||
|
return G.Flatten(mma)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MonadChain[A, B any](fa NonEmptyArray[A], f func(a A) NonEmptyArray[B]) NonEmptyArray[B] {
|
||||||
|
return G.MonadChain[NonEmptyArray[A], NonEmptyArray[B]](fa, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Chain[A, B any](f func(A) NonEmptyArray[B]) func(NonEmptyArray[A]) NonEmptyArray[B] {
|
||||||
|
return G.Chain[NonEmptyArray[A], NonEmptyArray[B]](f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MonadAp[B, A any](fab NonEmptyArray[func(A) B], fa NonEmptyArray[A]) NonEmptyArray[B] {
|
||||||
|
return G.MonadAp[NonEmptyArray[B]](fab, fa)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Ap[B, A any](fa NonEmptyArray[A]) func(NonEmptyArray[func(A) B]) NonEmptyArray[B] {
|
||||||
|
return G.Ap[NonEmptyArray[B], NonEmptyArray[func(A) B]](fa)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FoldMap maps and folds a [NonEmptyArray]. Map the [NonEmptyArray] passing each value to the iterating function. Then fold the results using the provided [Semigroup].
|
||||||
|
func FoldMap[A, B any](s S.Semigroup[B]) func(func(A) B) func(NonEmptyArray[A]) B {
|
||||||
|
return func(f func(A) B) func(NonEmptyArray[A]) B {
|
||||||
|
return func(as NonEmptyArray[A]) B {
|
||||||
|
return array.Reduce(Tail(as), func(cur B, a A) B {
|
||||||
|
return s.Concat(cur, f(a))
|
||||||
|
}, f(Head(as)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fold folds the [NonEmptyArray] using the provided [Semigroup].
|
||||||
|
func Fold[A any](s S.Semigroup[A]) func(NonEmptyArray[A]) A {
|
||||||
|
return func(as NonEmptyArray[A]) A {
|
||||||
|
return array.Reduce(Tail(as), s.Concat, Head(as))
|
||||||
|
}
|
||||||
|
}
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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
|
package array
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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
|
package array
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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
|
package array
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -9,3 +24,13 @@ import (
|
|||||||
func Sort[T any](ord O.Ord[T]) func(ma []T) []T {
|
func Sort[T any](ord O.Ord[T]) func(ma []T) []T {
|
||||||
return G.Sort[[]T](ord)
|
return G.Sort[[]T](ord)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SortByKey implements a stable sort on the array given the provided ordering on an extracted key
|
||||||
|
func SortByKey[K, T any](ord O.Ord[K], f func(T) K) func(ma []T) []T {
|
||||||
|
return G.SortByKey[[]T](ord, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SortBy implements a stable sort on the array given the provided ordering
|
||||||
|
func SortBy[T any](ord []O.Ord[T]) func(ma []T) []T {
|
||||||
|
return G.SortBy[[]T, []O.Ord[T]](ord)
|
||||||
|
}
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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
|
package array
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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
|
package array
|
||||||
|
|
||||||
import "github.com/IBM/fp-go/internal/array"
|
import "github.com/IBM/fp-go/internal/array"
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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
|
package array
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
17
array/uniq.go
Normal file
17
array/uniq.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package array
|
||||||
|
|
||||||
|
import (
|
||||||
|
G "github.com/IBM/fp-go/array/generic"
|
||||||
|
)
|
||||||
|
|
||||||
|
// StrictUniq converts an array of arbitrary items into an array or unique items
|
||||||
|
// where uniqueness is determined by the built-in uniqueness constraint
|
||||||
|
func StrictUniq[A comparable](as []A) []A {
|
||||||
|
return G.StrictUniq[[]A](as)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uniq converts an array of arbitrary items into an array or unique items
|
||||||
|
// where uniqueness is determined based on a key extractor function
|
||||||
|
func Uniq[A any, K comparable](f func(A) K) func(as []A) []A {
|
||||||
|
return G.Uniq[[]A](f)
|
||||||
|
}
|
14
array/uniq_test.go
Normal file
14
array/uniq_test.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package array
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestUniq(t *testing.T) {
|
||||||
|
data := From(1, 2, 3, 2, 4, 1)
|
||||||
|
|
||||||
|
uniq := StrictUniq(data)
|
||||||
|
assert.Equal(t, From(1, 2, 3, 4), uniq)
|
||||||
|
}
|
38
array/zip.go
Normal file
38
array/zip.go
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
// 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"
|
||||||
|
T "github.com/IBM/fp-go/tuple"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ZipWith applies a function to pairs of elements at the same index in two arrays, collecting the results in a new array. If one
|
||||||
|
// input array is short, excess elements of the longer array are discarded.
|
||||||
|
func ZipWith[FCT ~func(A, B) C, A, B, C any](fa []A, fb []B, f FCT) []C {
|
||||||
|
return G.ZipWith[[]A, []B, []C, FCT](fa, fb, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zip takes two arrays and returns an array of corresponding pairs. If one input array is short, excess elements of the
|
||||||
|
// longer array are discarded
|
||||||
|
func Zip[A, B any](fb []B) func([]A) []T.Tuple2[A, B] {
|
||||||
|
return G.Zip[[]A, []B, []T.Tuple2[A, B]](fb)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unzip is the function is reverse of [Zip]. Takes an array of pairs and return two corresponding arrays
|
||||||
|
func Unzip[A, B any](cs []T.Tuple2[A, B]) T.Tuple2[[]A, []B] {
|
||||||
|
return G.Unzip[[]A, []B, []T.Tuple2[A, B]](cs)
|
||||||
|
}
|
56
array/zip_test.go
Normal file
56
array/zip_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 (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
T "github.com/IBM/fp-go/tuple"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestZipWith(t *testing.T) {
|
||||||
|
left := From(1, 2, 3)
|
||||||
|
right := From("a", "b", "c", "d")
|
||||||
|
|
||||||
|
res := ZipWith(left, right, func(l int, r string) string {
|
||||||
|
return fmt.Sprintf("%s%d", r, l)
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(t, From("a1", "b2", "c3"), res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestZip(t *testing.T) {
|
||||||
|
left := From(1, 2, 3)
|
||||||
|
right := From("a", "b", "c", "d")
|
||||||
|
|
||||||
|
res := Zip[string](left)(right)
|
||||||
|
|
||||||
|
assert.Equal(t, From(T.MakeTuple2("a", 1), T.MakeTuple2("b", 2), T.MakeTuple2("c", 3)), res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnzip(t *testing.T) {
|
||||||
|
left := From(1, 2, 3)
|
||||||
|
right := From("a", "b", "c")
|
||||||
|
|
||||||
|
zipped := Zip[string](left)(right)
|
||||||
|
|
||||||
|
unzipped := Unzip(zipped)
|
||||||
|
|
||||||
|
assert.Equal(t, right, unzipped.F1)
|
||||||
|
assert.Equal(t, left, unzipped.F2)
|
||||||
|
}
|
109
assert/assert_test.go
Normal file
109
assert/assert_test.go
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
// 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 assert
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
E "github.com/IBM/fp-go/either"
|
||||||
|
EQ "github.com/IBM/fp-go/eq"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
errTest = fmt.Errorf("test failure")
|
||||||
|
|
||||||
|
// Eq is the equal predicate checking if objects are equal
|
||||||
|
Eq = EQ.FromEquals(assert.ObjectsAreEqual)
|
||||||
|
)
|
||||||
|
|
||||||
|
func wrap1[T any](wrapped func(t assert.TestingT, expected, actual any, msgAndArgs ...any) bool, t *testing.T, expected T) func(actual T) E.Either[error, T] {
|
||||||
|
return func(actual T) E.Either[error, T] {
|
||||||
|
ok := wrapped(t, expected, actual)
|
||||||
|
if ok {
|
||||||
|
return E.Of[error](actual)
|
||||||
|
}
|
||||||
|
return E.Left[T](errTest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotEqual tests if the expected and the actual values are not equal
|
||||||
|
func NotEqual[T any](t *testing.T, expected T) func(actual T) E.Either[error, T] {
|
||||||
|
return wrap1(assert.NotEqual, t, expected)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equal tests if the expected and the actual values are equal
|
||||||
|
func Equal[T any](t *testing.T, expected T) func(actual T) E.Either[error, T] {
|
||||||
|
return wrap1(assert.Equal, t, expected)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Length tests if an array has the expected length
|
||||||
|
func Length[T any](t *testing.T, expected int) func(actual []T) E.Either[error, []T] {
|
||||||
|
return func(actual []T) E.Either[error, []T] {
|
||||||
|
ok := assert.Len(t, actual, expected)
|
||||||
|
if ok {
|
||||||
|
return E.Of[error](actual)
|
||||||
|
}
|
||||||
|
return E.Left[[]T](errTest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NoError validates that there is no error
|
||||||
|
func NoError[T any](t *testing.T) func(actual E.Either[error, T]) E.Either[error, T] {
|
||||||
|
return func(actual E.Either[error, T]) E.Either[error, T] {
|
||||||
|
return E.MonadFold(actual, func(e error) E.Either[error, T] {
|
||||||
|
assert.NoError(t, e)
|
||||||
|
return E.Left[T](e)
|
||||||
|
}, func(value T) E.Either[error, T] {
|
||||||
|
assert.NoError(t, nil)
|
||||||
|
return E.Right[error](value)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ArrayContains tests if a value is contained in an array
|
||||||
|
func ArrayContains[T any](t *testing.T, expected T) func(actual []T) E.Either[error, []T] {
|
||||||
|
return func(actual []T) E.Either[error, []T] {
|
||||||
|
ok := assert.Contains(t, actual, expected)
|
||||||
|
if ok {
|
||||||
|
return E.Of[error](actual)
|
||||||
|
}
|
||||||
|
return E.Left[[]T](errTest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContainsKey tests if a key is contained in a map
|
||||||
|
func ContainsKey[T any, K comparable](t *testing.T, expected K) func(actual map[K]T) E.Either[error, map[K]T] {
|
||||||
|
return func(actual map[K]T) E.Either[error, map[K]T] {
|
||||||
|
ok := assert.Contains(t, actual, expected)
|
||||||
|
if ok {
|
||||||
|
return E.Of[error](actual)
|
||||||
|
}
|
||||||
|
return E.Left[map[K]T](errTest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotContainsKey tests if a key is not contained in a map
|
||||||
|
func NotContainsKey[T any, K comparable](t *testing.T, expected K) func(actual map[K]T) E.Either[error, map[K]T] {
|
||||||
|
return func(actual map[K]T) E.Either[error, map[K]T] {
|
||||||
|
ok := assert.NotContains(t, actual, expected)
|
||||||
|
if ok {
|
||||||
|
return E.Of[error](actual)
|
||||||
|
}
|
||||||
|
return E.Left[map[K]T](errTest)
|
||||||
|
}
|
||||||
|
}
|
59
boolean/boolean.go
Normal file
59
boolean/boolean.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 boolean
|
||||||
|
|
||||||
|
import (
|
||||||
|
EQ "github.com/IBM/fp-go/eq"
|
||||||
|
M "github.com/IBM/fp-go/monoid"
|
||||||
|
O "github.com/IBM/fp-go/ord"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// MonoidAny is the boolean [M.Monoid] under disjunction
|
||||||
|
MonoidAny = M.MakeMonoid(
|
||||||
|
func(l, r bool) bool {
|
||||||
|
return l || r
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
|
||||||
|
// MonoidAll is the boolean [M.Monoid] under conjuction
|
||||||
|
MonoidAll = M.MakeMonoid(
|
||||||
|
func(l, r bool) bool {
|
||||||
|
return l && r
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
|
||||||
|
// Eq is the equals predicate for boolean
|
||||||
|
Eq = EQ.FromStrictEquals[bool]()
|
||||||
|
|
||||||
|
// Ord is the strict ordering for boolean
|
||||||
|
Ord = O.MakeOrd(func(l, r bool) int {
|
||||||
|
if l {
|
||||||
|
if r {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return +1
|
||||||
|
}
|
||||||
|
if r {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}, func(l, r bool) bool {
|
||||||
|
return l == r
|
||||||
|
})
|
||||||
|
)
|
64
bounded/bounded.go
Normal file
64
bounded/bounded.go
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
// Copyright (c) 2023 IBM Corp.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package bounded
|
||||||
|
|
||||||
|
import (
|
||||||
|
O "github.com/IBM/fp-go/ord"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Bounded[T any] interface {
|
||||||
|
O.Ord[T]
|
||||||
|
Top() T
|
||||||
|
Bottom() T
|
||||||
|
}
|
||||||
|
|
||||||
|
type bounded[T any] struct {
|
||||||
|
c func(x, y T) int
|
||||||
|
e func(x, y T) bool
|
||||||
|
t T
|
||||||
|
b T
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self bounded[T]) Equals(x, y T) bool {
|
||||||
|
return self.e(x, y)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self bounded[T]) Compare(x, y T) int {
|
||||||
|
return self.c(x, y)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self bounded[T]) Top() T {
|
||||||
|
return self.t
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self bounded[T]) Bottom() T {
|
||||||
|
return self.b
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeBounded creates an instance of a bounded type
|
||||||
|
func MakeBounded[T any](o O.Ord[T], t, b T) Bounded[T] {
|
||||||
|
return bounded[T]{c: o.Compare, e: o.Equals, t: t, b: b}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clamp returns a function that clamps against the bounds defined in the bounded type
|
||||||
|
func Clamp[T any](b Bounded[T]) func(T) T {
|
||||||
|
return O.Clamp[T](b)(b.Bottom(), b.Top())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reverse reverses the ordering and swaps the bounds
|
||||||
|
func Reverse[T any](b Bounded[T]) Bounded[T] {
|
||||||
|
return MakeBounded(O.Reverse[T](b), b.Bottom(), b.Top())
|
||||||
|
}
|
@@ -1,5 +1,24 @@
|
|||||||
|
// 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 bytes
|
package bytes
|
||||||
|
|
||||||
func ToString(a []byte) string {
|
func ToString(a []byte) string {
|
||||||
return string(a)
|
return string(a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Size(as []byte) int {
|
||||||
|
return len(as)
|
||||||
|
}
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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 bytes
|
package bytes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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 bytes
|
package bytes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
17
cli/apply.go
17
cli/apply.go
@@ -1,3 +1,18 @@
|
|||||||
|
// 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 cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -373,7 +388,7 @@ func generateApplyHelpers(filename string, count int) error {
|
|||||||
// some header
|
// some header
|
||||||
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
||||||
fmt.Fprintln(f, "// This file was generated by robots at")
|
fmt.Fprintln(f, "// This file was generated by robots at")
|
||||||
fmt.Fprintf(f, "// %s\n", time.Now())
|
fmt.Fprintf(f, "// %s\n\n", time.Now())
|
||||||
|
|
||||||
fmt.Fprintf(f, "package %s\n\n", pkg)
|
fmt.Fprintf(f, "package %s\n\n", pkg)
|
||||||
|
|
||||||
|
17
cli/bind.go
17
cli/bind.go
@@ -1,3 +1,18 @@
|
|||||||
|
// 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 cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -251,7 +266,7 @@ func generateBindHelpers(filename string, count int) error {
|
|||||||
// some header
|
// some header
|
||||||
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
||||||
fmt.Fprintln(f, "// This file was generated by robots at")
|
fmt.Fprintln(f, "// This file was generated by robots at")
|
||||||
fmt.Fprintf(f, "// %s\n", time.Now())
|
fmt.Fprintf(f, "// %s\n\n", time.Now())
|
||||||
|
|
||||||
fmt.Fprintf(f, "package %s\n", pkg)
|
fmt.Fprintf(f, "package %s\n", pkg)
|
||||||
|
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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 cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -16,5 +31,8 @@ func Commands() []*C.Command {
|
|||||||
ContextReaderIOEitherCommand(),
|
ContextReaderIOEitherCommand(),
|
||||||
ReaderIOEitherCommand(),
|
ReaderIOEitherCommand(),
|
||||||
ReaderCommand(),
|
ReaderCommand(),
|
||||||
|
IOEitherCommand(),
|
||||||
|
IOCommand(),
|
||||||
|
IOOptionCommand(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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 cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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 cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -5,10 +20,307 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
C "github.com/urfave/cli/v2"
|
C "github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func generateNestedCallbacks(i, total int) string {
|
||||||
|
var buf strings.Builder
|
||||||
|
for j := i; j < total; j++ {
|
||||||
|
if j > i {
|
||||||
|
buf.WriteString(" ")
|
||||||
|
}
|
||||||
|
buf.WriteString(fmt.Sprintf("func(T%d)", j+1))
|
||||||
|
}
|
||||||
|
if i > 0 {
|
||||||
|
buf.WriteString(" ")
|
||||||
|
}
|
||||||
|
buf.WriteString(tupleType("T")(total))
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateContextReaderIOEitherTraverseTuple(suffix string) func(f, fg *os.File, i int) {
|
||||||
|
return func(f, fg *os.File, i int) {
|
||||||
|
// tupleT type
|
||||||
|
tupleT := tupleType("T")(i)
|
||||||
|
tupleA := tupleType("A")(i)
|
||||||
|
|
||||||
|
// non-generic version
|
||||||
|
// generic version
|
||||||
|
fmt.Fprintf(f, "\n// Traverse%sTuple%d converts a [T.Tuple%d] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple%d].\n", suffix, i, i, i)
|
||||||
|
fmt.Fprintf(f, "func Traverse%sTuple%d[", suffix, i)
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "F%d ~func(A%d) ReaderIOEither[T%d]", j+1, j+1, j+1)
|
||||||
|
}
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(f, ", A%d, T%d", j+1, j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, " any](")
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "f%d F%d", j+1, j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, ") func(%s) ReaderIOEither[%s] {\n", tupleA, tupleT)
|
||||||
|
fmt.Fprintf(f, " return G.Traverse%sTuple%d[ReaderIOEither[%s]](", suffix, i, tupleT)
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "f%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, ")\n")
|
||||||
|
fmt.Fprintf(f, "}\n")
|
||||||
|
|
||||||
|
// generic version
|
||||||
|
fmt.Fprintf(fg, "\n// Traverse%sTuple%d converts a [T.Tuple%d] of readers into a reader of a [T.Tuple%d].\n", suffix, i, i, i)
|
||||||
|
fmt.Fprintf(fg, "func Traverse%sTuple%d[\n", suffix, i)
|
||||||
|
fmt.Fprintf(fg, " GR_TUPLE%d ~func(context.Context) GIO_TUPLE%d,\n", i, i)
|
||||||
|
// the transformation functions
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(fg, " F%d ~func(A%d) GR_T%d,\n", j+1, j+1, j+1)
|
||||||
|
}
|
||||||
|
// the readers
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(fg, " GR_T%d ~func(context.Context) GIO_T%d,\n", j+1, j+1)
|
||||||
|
}
|
||||||
|
// the tuples
|
||||||
|
fmt.Fprintf(fg, " GIO_TUPLE%d ~func() E.Either[error, %s],\n", i, tupleT)
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(fg, " GIO_T%d ~func() E.Either[error, T%d],\n", j+1, j+1)
|
||||||
|
}
|
||||||
|
// input and result parameters
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(fg, " A%d,\n", j+1)
|
||||||
|
fmt.Fprintf(fg, " T%d", j+1)
|
||||||
|
if j < i-1 {
|
||||||
|
fmt.Fprintf(fg, ",\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, " any](")
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(fg, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, "f%d F%d", j+1, j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, ") func(%s) GR_TUPLE%d {\n", tupleA, i)
|
||||||
|
fmt.Fprintf(fg, " return func(t %s) GR_TUPLE%d {\n", tupleA, i)
|
||||||
|
fmt.Fprintf(fg, " return A.TraverseTuple%d(\n", i)
|
||||||
|
// map call
|
||||||
|
var cr string
|
||||||
|
if i > 1 {
|
||||||
|
cb := generateNestedCallbacks(1, i)
|
||||||
|
cio := fmt.Sprintf("func() E.Either[error, %s]", cb)
|
||||||
|
cr = fmt.Sprintf("func(context.Context) %s", cio)
|
||||||
|
} else {
|
||||||
|
cr = fmt.Sprintf("GR_TUPLE%d", i)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, " Map[GR_T%d, %s, GIO_T%d],\n", 1, cr, 1)
|
||||||
|
// the apply calls
|
||||||
|
for j := 1; j < i; j++ {
|
||||||
|
if j < i-1 {
|
||||||
|
cb := generateNestedCallbacks(j+1, i)
|
||||||
|
cio := fmt.Sprintf("func() E.Either[error, %s]", cb)
|
||||||
|
cr = fmt.Sprintf("func(context.Context) %s", cio)
|
||||||
|
} else {
|
||||||
|
cr = fmt.Sprintf("GR_TUPLE%d", i)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, " Ap%s[%s, func(context.Context) func() E.Either[error, %s], GR_T%d],\n", suffix, cr, generateNestedCallbacks(j, i), j+1)
|
||||||
|
}
|
||||||
|
// function parameters
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(fg, " f%d,\n", j+1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// raw parameters
|
||||||
|
fmt.Fprintf(fg, " t,\n")
|
||||||
|
|
||||||
|
fmt.Fprintf(fg, " )\n")
|
||||||
|
fmt.Fprintf(fg, " }\n")
|
||||||
|
fmt.Fprintf(fg, "}\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateContextReaderIOEitherSequenceTuple(suffix string) func(f, fg *os.File, i int) {
|
||||||
|
return func(f, fg *os.File, i int) {
|
||||||
|
// tuple type
|
||||||
|
tuple := tupleType("T")(i)
|
||||||
|
|
||||||
|
// non-generic version
|
||||||
|
// generic version
|
||||||
|
fmt.Fprintf(f, "\n// Sequence%sTuple%d converts a [T.Tuple%d] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple%d].\n", suffix, i, i, i)
|
||||||
|
fmt.Fprintf(f, "func Sequence%sTuple%d[", suffix, i)
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "T%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, " any](t T.Tuple%d[", i)
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "ReaderIOEither[T%d]", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "]) ReaderIOEither[%s] {\n", tuple)
|
||||||
|
fmt.Fprintf(f, " return G.Sequence%sTuple%d[ReaderIOEither[%s]](t)\n", suffix, i, tuple)
|
||||||
|
fmt.Fprintf(f, "}\n")
|
||||||
|
|
||||||
|
// generic version
|
||||||
|
fmt.Fprintf(fg, "\n// Sequence%sTuple%d converts a [T.Tuple%d] of readers into a reader of a [T.Tuple%d].\n", suffix, i, i, i)
|
||||||
|
fmt.Fprintf(fg, "func Sequence%sTuple%d[\n", suffix, i)
|
||||||
|
|
||||||
|
fmt.Fprintf(fg, " GR_TUPLE%d ~func(context.Context) GIO_TUPLE%d,\n", i, i)
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(fg, " GR_T%d ~func(context.Context) GIO_T%d,\n", j+1, j+1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(fg, " GIO_TUPLE%d ~func() E.Either[error, %s],\n", i, tuple)
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(fg, " GIO_T%d ~func() E.Either[error, T%d],\n", j+1, j+1)
|
||||||
|
}
|
||||||
|
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(fg, " T%d", j+1)
|
||||||
|
if j < i-1 {
|
||||||
|
fmt.Fprintf(fg, ",\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, " any](t T.Tuple%d[", i)
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(fg, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, "GR_T%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, "]) GR_TUPLE%d {\n", i)
|
||||||
|
fmt.Fprintf(fg, " return A.SequenceTuple%d(\n", i)
|
||||||
|
// map call
|
||||||
|
var cr string
|
||||||
|
if i > 1 {
|
||||||
|
cb := generateNestedCallbacks(1, i)
|
||||||
|
cio := fmt.Sprintf("func() E.Either[error, %s]", cb)
|
||||||
|
cr = fmt.Sprintf("func(context.Context) %s", cio)
|
||||||
|
} else {
|
||||||
|
cr = fmt.Sprintf("GR_TUPLE%d", i)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, " Map[GR_T%d, %s, GIO_T%d],\n", 1, cr, 1)
|
||||||
|
// the apply calls
|
||||||
|
for j := 1; j < i; j++ {
|
||||||
|
if j < i-1 {
|
||||||
|
cb := generateNestedCallbacks(j+1, i)
|
||||||
|
cio := fmt.Sprintf("func() E.Either[error, %s]", cb)
|
||||||
|
cr = fmt.Sprintf("func(context.Context) %s", cio)
|
||||||
|
} else {
|
||||||
|
cr = fmt.Sprintf("GR_TUPLE%d", i)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, " Ap%s[%s, func(context.Context) func() E.Either[error, %s], GR_T%d],\n", suffix, cr, generateNestedCallbacks(j, i), j+1)
|
||||||
|
}
|
||||||
|
// raw parameters
|
||||||
|
fmt.Fprintf(fg, " t,\n")
|
||||||
|
|
||||||
|
fmt.Fprintf(fg, " )\n")
|
||||||
|
fmt.Fprintf(fg, "}\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateContextReaderIOEitherSequenceT(suffix string) func(f, fg *os.File, i int) {
|
||||||
|
return func(f, fg *os.File, i int) {
|
||||||
|
// tuple type
|
||||||
|
tuple := tupleType("T")(i)
|
||||||
|
|
||||||
|
// non-generic version
|
||||||
|
// generic version
|
||||||
|
fmt.Fprintf(f, "\n// Sequence%sT%d converts %d [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple%d].\n", suffix, i, i, i)
|
||||||
|
fmt.Fprintf(f, "func Sequence%sT%d[", suffix, i)
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "T%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, " any](")
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "t%d ReaderIOEither[T%d]", j+1, j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, ") ReaderIOEither[%s] {\n", tuple)
|
||||||
|
fmt.Fprintf(f, " return G.Sequence%sT%d[ReaderIOEither[%s]](", suffix, i, tuple)
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "t%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, ")\n")
|
||||||
|
fmt.Fprintf(f, "}\n")
|
||||||
|
|
||||||
|
// generic version
|
||||||
|
fmt.Fprintf(fg, "\n// Sequence%sT%d converts %d readers into a reader of a [T.Tuple%d].\n", suffix, i, i, i)
|
||||||
|
fmt.Fprintf(fg, "func Sequence%sT%d[\n", suffix, i)
|
||||||
|
|
||||||
|
fmt.Fprintf(fg, " GR_TUPLE%d ~func(context.Context) GIO_TUPLE%d,\n", i, i)
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(fg, " GR_T%d ~func(context.Context) GIO_T%d,\n", j+1, j+1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(fg, " GIO_TUPLE%d ~func() E.Either[error, %s],\n", i, tuple)
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(fg, " GIO_T%d ~func() E.Either[error, T%d],\n", j+1, j+1)
|
||||||
|
}
|
||||||
|
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(fg, " T%d", j+1)
|
||||||
|
if j < i-1 {
|
||||||
|
fmt.Fprintf(fg, ",\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, " any](\n")
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(fg, " t%d GR_T%d,\n", j+1, j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, ") GR_TUPLE%d {\n", i)
|
||||||
|
fmt.Fprintf(fg, " return A.SequenceT%d(\n", i)
|
||||||
|
// map call
|
||||||
|
var cr string
|
||||||
|
if i > 1 {
|
||||||
|
cb := generateNestedCallbacks(1, i)
|
||||||
|
cio := fmt.Sprintf("func() E.Either[error, %s]", cb)
|
||||||
|
cr = fmt.Sprintf("func(context.Context) %s", cio)
|
||||||
|
} else {
|
||||||
|
cr = fmt.Sprintf("GR_TUPLE%d", i)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, " Map[GR_T%d, %s, GIO_T%d],\n", 1, cr, 1)
|
||||||
|
// the apply calls
|
||||||
|
for j := 1; j < i; j++ {
|
||||||
|
if j < i-1 {
|
||||||
|
cb := generateNestedCallbacks(j+1, i)
|
||||||
|
cio := fmt.Sprintf("func() E.Either[error, %s]", cb)
|
||||||
|
cr = fmt.Sprintf("func(context.Context) %s", cio)
|
||||||
|
} else {
|
||||||
|
cr = fmt.Sprintf("GR_TUPLE%d", i)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, " Ap%s[%s, func(context.Context) func() E.Either[error, %s], GR_T%d],\n", suffix, cr, generateNestedCallbacks(j, i), j+1)
|
||||||
|
}
|
||||||
|
// raw parameters
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(fg, " t%d,\n", j+1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(fg, " )\n")
|
||||||
|
fmt.Fprintf(fg, "}\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func generateContextReaderIOEitherEitherize(f, fg *os.File, i int) {
|
func generateContextReaderIOEitherEitherize(f, fg *os.File, i int) {
|
||||||
// non generic version
|
// non generic version
|
||||||
fmt.Fprintf(f, "\n// Eitherize%d converts a function with %d parameters returning a tuple into a function with %d parameters returning a [ReaderIOEither[R]]\n// The inverse function is [Uneitherize%d]\n", i, i, i, i)
|
fmt.Fprintf(f, "\n// Eitherize%d converts a function with %d parameters returning a tuple into a function with %d parameters returning a [ReaderIOEither[R]]\n// The inverse function is [Uneitherize%d]\n", i, i, i, i)
|
||||||
@@ -90,6 +402,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
G "github.com/IBM/fp-go/context/%s/generic"
|
G "github.com/IBM/fp-go/context/%s/generic"
|
||||||
|
T "github.com/IBM/fp-go/tuple"
|
||||||
)
|
)
|
||||||
`, pkg)
|
`, pkg)
|
||||||
|
|
||||||
@@ -101,6 +414,8 @@ import (
|
|||||||
|
|
||||||
E "github.com/IBM/fp-go/either"
|
E "github.com/IBM/fp-go/either"
|
||||||
RE "github.com/IBM/fp-go/readerioeither/generic"
|
RE "github.com/IBM/fp-go/readerioeither/generic"
|
||||||
|
A "github.com/IBM/fp-go/internal/apply"
|
||||||
|
T "github.com/IBM/fp-go/tuple"
|
||||||
)
|
)
|
||||||
`)
|
`)
|
||||||
|
|
||||||
@@ -109,6 +424,18 @@ import (
|
|||||||
for i := 1; i <= count; i++ {
|
for i := 1; i <= count; i++ {
|
||||||
// eitherize
|
// eitherize
|
||||||
generateContextReaderIOEitherEitherize(f, fg, i)
|
generateContextReaderIOEitherEitherize(f, fg, i)
|
||||||
|
// sequenceT
|
||||||
|
generateContextReaderIOEitherSequenceT("")(f, fg, i)
|
||||||
|
generateContextReaderIOEitherSequenceT("Seq")(f, fg, i)
|
||||||
|
generateContextReaderIOEitherSequenceT("Par")(f, fg, i)
|
||||||
|
// sequenceTuple
|
||||||
|
generateContextReaderIOEitherSequenceTuple("")(f, fg, i)
|
||||||
|
generateContextReaderIOEitherSequenceTuple("Seq")(f, fg, i)
|
||||||
|
generateContextReaderIOEitherSequenceTuple("Par")(f, fg, i)
|
||||||
|
// traverseTuple
|
||||||
|
generateContextReaderIOEitherTraverseTuple("")(f, fg, i)
|
||||||
|
generateContextReaderIOEitherTraverseTuple("Seq")(f, fg, i)
|
||||||
|
generateContextReaderIOEitherTraverseTuple("Par")(f, fg, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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 cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -100,16 +115,14 @@ func generateEitherize(f *os.File, i int) {
|
|||||||
fmt.Fprintf(f, "t%d T%d", j, j)
|
fmt.Fprintf(f, "t%d T%d", j, j)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(f, ") Either[error, R] {\n")
|
fmt.Fprintf(f, ") Either[error, R] {\n")
|
||||||
fmt.Fprintf(f, " return TryCatchError(func() (R, error) {\n")
|
fmt.Fprintf(f, " return TryCatchError(f(")
|
||||||
fmt.Fprintf(f, " return f(")
|
|
||||||
for j := 0; j < i; j++ {
|
for j := 0; j < i; j++ {
|
||||||
if j > 0 {
|
if j > 0 {
|
||||||
fmt.Fprintf(f, ", ")
|
fmt.Fprintf(f, ", ")
|
||||||
}
|
}
|
||||||
fmt.Fprintf(f, "t%d", j)
|
fmt.Fprintf(f, "t%d", j)
|
||||||
}
|
}
|
||||||
fmt.Fprintln(f, ")")
|
fmt.Fprintln(f, "))")
|
||||||
fmt.Fprintln(f, " })")
|
|
||||||
fmt.Fprintln(f, " }")
|
fmt.Fprintln(f, " }")
|
||||||
fmt.Fprintln(f, "}")
|
fmt.Fprintln(f, "}")
|
||||||
}
|
}
|
||||||
@@ -135,7 +148,7 @@ func generateEitherHelpers(filename string, count int) error {
|
|||||||
// some header
|
// some header
|
||||||
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
||||||
fmt.Fprintln(f, "// This file was generated by robots at")
|
fmt.Fprintln(f, "// This file was generated by robots at")
|
||||||
fmt.Fprintf(f, "// %s\n", time.Now())
|
fmt.Fprintf(f, "// %s\n\n", time.Now())
|
||||||
|
|
||||||
fmt.Fprintf(f, "package %s\n\n", pkg)
|
fmt.Fprintf(f, "package %s\n\n", pkg)
|
||||||
|
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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 cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -12,5 +27,5 @@ func writePackage(f *os.File, pkg string) {
|
|||||||
// some header
|
// some header
|
||||||
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
||||||
fmt.Fprintln(f, "// This file was generated by robots at")
|
fmt.Fprintln(f, "// This file was generated by robots at")
|
||||||
fmt.Fprintf(f, "// %s\n", time.Now())
|
fmt.Fprintf(f, "// %s\n\n", time.Now())
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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 cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -47,7 +62,7 @@ func generateIdentityHelpers(filename string, count int) error {
|
|||||||
// some header
|
// some header
|
||||||
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
||||||
fmt.Fprintln(f, "// This file was generated by robots at")
|
fmt.Fprintln(f, "// This file was generated by robots at")
|
||||||
fmt.Fprintf(f, "// %s\n", time.Now())
|
fmt.Fprintf(f, "// %s\n\n", time.Now())
|
||||||
|
|
||||||
fmt.Fprintf(f, "package %s\n\n", pkg)
|
fmt.Fprintf(f, "package %s\n\n", pkg)
|
||||||
|
|
||||||
|
136
cli/io.go
Normal file
136
cli/io.go
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
// 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 cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
A "github.com/IBM/fp-go/array"
|
||||||
|
C "github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func nonGenericIO(param string) string {
|
||||||
|
return fmt.Sprintf("IO[%s]", param)
|
||||||
|
}
|
||||||
|
|
||||||
|
func genericIO(param string) string {
|
||||||
|
return fmt.Sprintf("func() %s", param)
|
||||||
|
}
|
||||||
|
|
||||||
|
var extrasIO = A.Empty[string]()
|
||||||
|
|
||||||
|
func generateIOSequenceT(f, fg *os.File, i int) {
|
||||||
|
generateGenericSequenceT(nonGenericIO, genericIO, extrasIO)(f, fg, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateIOSequenceTuple(f, fg *os.File, i int) {
|
||||||
|
generateGenericSequenceTuple(nonGenericIO, genericIO, extrasIO)(f, fg, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateIOTraverseTuple(f, fg *os.File, i int) {
|
||||||
|
generateGenericTraverseTuple(nonGenericIO, genericIO, extrasIO)(f, fg, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateIOHelpers(filename string, count int) error {
|
||||||
|
dir, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
absDir, err := filepath.Abs(dir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pkg := filepath.Base(absDir)
|
||||||
|
f, err := os.Create(filepath.Clean(filename))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
// construct subdirectory
|
||||||
|
genFilename := filepath.Join("generic", filename)
|
||||||
|
err = os.MkdirAll("generic", os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fg, err := os.Create(filepath.Clean(genFilename))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fg.Close()
|
||||||
|
|
||||||
|
// log
|
||||||
|
log.Printf("Generating code in [%s] for package [%s] with [%d] repetitions ...", filename, pkg, count)
|
||||||
|
|
||||||
|
// some header
|
||||||
|
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
||||||
|
fmt.Fprintln(f, "// This file was generated by robots at")
|
||||||
|
fmt.Fprintf(f, "// %s\n\n", time.Now())
|
||||||
|
|
||||||
|
fmt.Fprintf(f, "package %s\n\n", pkg)
|
||||||
|
|
||||||
|
fmt.Fprintf(f, `
|
||||||
|
import (
|
||||||
|
G "github.com/IBM/fp-go/%s/generic"
|
||||||
|
T "github.com/IBM/fp-go/tuple"
|
||||||
|
)
|
||||||
|
`, pkg)
|
||||||
|
|
||||||
|
// some header
|
||||||
|
fmt.Fprintln(fg, "// Code generated by go generate; DO NOT EDIT.")
|
||||||
|
fmt.Fprintln(fg, "// This file was generated by robots at")
|
||||||
|
fmt.Fprintf(fg, "// %s\n", time.Now())
|
||||||
|
|
||||||
|
fmt.Fprintf(fg, "package generic\n\n")
|
||||||
|
|
||||||
|
fmt.Fprintf(fg, `
|
||||||
|
import (
|
||||||
|
T "github.com/IBM/fp-go/tuple"
|
||||||
|
A "github.com/IBM/fp-go/internal/apply"
|
||||||
|
)
|
||||||
|
`)
|
||||||
|
|
||||||
|
for i := 1; i <= count; i++ {
|
||||||
|
// sequenceT
|
||||||
|
generateIOSequenceT(f, fg, i)
|
||||||
|
// sequenceTuple
|
||||||
|
generateIOSequenceTuple(f, fg, i)
|
||||||
|
// traverseTuple
|
||||||
|
generateIOTraverseTuple(f, fg, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func IOCommand() *C.Command {
|
||||||
|
return &C.Command{
|
||||||
|
Name: "io",
|
||||||
|
Usage: "generate code for IO",
|
||||||
|
Flags: []C.Flag{
|
||||||
|
flagCount,
|
||||||
|
flagFilename,
|
||||||
|
},
|
||||||
|
Action: func(ctx *C.Context) error {
|
||||||
|
return generateIOHelpers(
|
||||||
|
ctx.String(keyFilename),
|
||||||
|
ctx.Int(keyCount),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
282
cli/ioeither.go
Normal file
282
cli/ioeither.go
Normal file
@@ -0,0 +1,282 @@
|
|||||||
|
// 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 cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
A "github.com/IBM/fp-go/array"
|
||||||
|
C "github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// [GA ~func() ET.Either[E, A], GB ~func() ET.Either[E, B], GTAB ~func() ET.Either[E, T.Tuple2[A, B]], E, A, B any](a GA, b GB) GTAB {
|
||||||
|
|
||||||
|
func nonGenericIOEither(param string) string {
|
||||||
|
return fmt.Sprintf("IOEither[E, %s]", param)
|
||||||
|
}
|
||||||
|
|
||||||
|
func genericIOEither(param string) string {
|
||||||
|
return fmt.Sprintf("func() ET.Either[E, %s]", param)
|
||||||
|
}
|
||||||
|
|
||||||
|
var extrasIOEither = A.From("E")
|
||||||
|
|
||||||
|
func generateIOEitherSequenceT(f, fg *os.File, i int) {
|
||||||
|
generateGenericSequenceT(nonGenericIOEither, genericIOEither, extrasIOEither)(f, fg, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateIOEitherSequenceTuple(f, fg *os.File, i int) {
|
||||||
|
generateGenericSequenceTuple(nonGenericIOEither, genericIOEither, extrasIOEither)(f, fg, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateIOEitherTraverseTuple(f, fg *os.File, i int) {
|
||||||
|
generateGenericTraverseTuple(nonGenericIOEither, genericIOEither, extrasIOEither)(f, fg, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateIOEitherUneitherize(f, fg *os.File, i int) {
|
||||||
|
// non generic version
|
||||||
|
fmt.Fprintf(f, "\n// Uneitherize%d converts a function with %d parameters returning a tuple into a function with %d parameters returning a [IOEither[error, R]]\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+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, ") IOEither[error, R]")
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(f, ", T%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, ", R any](f F) func(")
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "T%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, ") (R, error) {\n")
|
||||||
|
fmt.Fprintf(f, " return G.Uneitherize%d[IOEither[error, R]](f)\n", i)
|
||||||
|
fmt.Fprintln(f, "}")
|
||||||
|
|
||||||
|
// generic version
|
||||||
|
fmt.Fprintf(fg, "\n// Uneitherize%d converts a function with %d parameters returning a tuple into a function with %d parameters returning a [GIOA]\n", i, i, i)
|
||||||
|
fmt.Fprintf(fg, "func Uneitherize%d[GIOA ~func() ET.Either[error, R], GTA ~func(", i)
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(fg, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, "T%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, ") GIOA")
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(fg, ", T%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, ", R any](f GTA) func(")
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(fg, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, "T%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, ") (R, error) {\n")
|
||||||
|
fmt.Fprintf(fg, " return func(")
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(fg, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, "t%d T%d", j+1, j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, ") (R, error) {\n")
|
||||||
|
fmt.Fprintf(fg, " return ET.Unwrap(f(")
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(fg, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, "t%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, ")())\n")
|
||||||
|
fmt.Fprintf(fg, " }\n")
|
||||||
|
fmt.Fprintf(fg, "}\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateIOEitherEitherize(f, fg *os.File, i int) {
|
||||||
|
// non generic version
|
||||||
|
fmt.Fprintf(f, "\n// Eitherize%d converts a function with %d parameters returning a tuple into a function with %d parameters returning a [IOEither[error, R]]\n", i, i+1, i)
|
||||||
|
fmt.Fprintf(f, "func Eitherize%d[F ~func(", i)
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "T%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, ") (R, error)")
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(f, ", T%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, ", R any](f F) func(")
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "T%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, ") IOEither[error, R] {\n")
|
||||||
|
fmt.Fprintf(f, " return G.Eitherize%d[IOEither[error, R]](f)\n", i)
|
||||||
|
fmt.Fprintln(f, "}")
|
||||||
|
|
||||||
|
// generic version
|
||||||
|
fmt.Fprintf(fg, "\n// Eitherize%d converts a function with %d parameters returning a tuple into a function with %d parameters returning a [GIOA]\n", i, i, i)
|
||||||
|
fmt.Fprintf(fg, "func Eitherize%d[GIOA ~func() ET.Either[error, R], F ~func(", i)
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(fg, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, "T%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, ") (R, error)")
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(fg, ", T%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, ", R any](f F) func(")
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(fg, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, "T%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, ") GIOA {\n")
|
||||||
|
fmt.Fprintf(fg, " e := ET.Eitherize%d(f)\n", i)
|
||||||
|
fmt.Fprintf(fg, " return func(")
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(fg, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, "t%d T%d", j+1, j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, ") GIOA {\n")
|
||||||
|
fmt.Fprintf(fg, " return func() ET.Either[error, R] {\n")
|
||||||
|
fmt.Fprintf(fg, " return e(")
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(fg, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, "t%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, ")\n")
|
||||||
|
fmt.Fprintf(fg, " }}\n")
|
||||||
|
fmt.Fprintf(fg, "}\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateIOEitherHelpers(filename string, count int) error {
|
||||||
|
dir, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
absDir, err := filepath.Abs(dir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pkg := filepath.Base(absDir)
|
||||||
|
f, err := os.Create(filepath.Clean(filename))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
// construct subdirectory
|
||||||
|
genFilename := filepath.Join("generic", filename)
|
||||||
|
err = os.MkdirAll("generic", os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fg, err := os.Create(filepath.Clean(genFilename))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fg.Close()
|
||||||
|
|
||||||
|
// log
|
||||||
|
log.Printf("Generating code in [%s] for package [%s] with [%d] repetitions ...", filename, pkg, count)
|
||||||
|
|
||||||
|
// some header
|
||||||
|
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
||||||
|
fmt.Fprintln(f, "// This file was generated by robots at")
|
||||||
|
fmt.Fprintf(f, "// %s\n\n", time.Now())
|
||||||
|
|
||||||
|
fmt.Fprintf(f, "package %s\n\n", pkg)
|
||||||
|
|
||||||
|
fmt.Fprintf(f, `
|
||||||
|
import (
|
||||||
|
G "github.com/IBM/fp-go/%s/generic"
|
||||||
|
T "github.com/IBM/fp-go/tuple"
|
||||||
|
)
|
||||||
|
`, pkg)
|
||||||
|
|
||||||
|
// some header
|
||||||
|
fmt.Fprintln(fg, "// Code generated by go generate; DO NOT EDIT.")
|
||||||
|
fmt.Fprintln(fg, "// This file was generated by robots at")
|
||||||
|
fmt.Fprintf(fg, "// %s\n", time.Now())
|
||||||
|
|
||||||
|
fmt.Fprintf(fg, "package generic\n\n")
|
||||||
|
|
||||||
|
fmt.Fprintf(fg, `
|
||||||
|
import (
|
||||||
|
ET "github.com/IBM/fp-go/either"
|
||||||
|
T "github.com/IBM/fp-go/tuple"
|
||||||
|
A "github.com/IBM/fp-go/internal/apply"
|
||||||
|
)
|
||||||
|
`)
|
||||||
|
|
||||||
|
// eitherize
|
||||||
|
generateIOEitherEitherize(f, fg, 0)
|
||||||
|
// uneitherize
|
||||||
|
generateIOEitherUneitherize(f, fg, 0)
|
||||||
|
|
||||||
|
for i := 1; i <= count; i++ {
|
||||||
|
// eitherize
|
||||||
|
generateIOEitherEitherize(f, fg, i)
|
||||||
|
// uneitherize
|
||||||
|
generateIOEitherUneitherize(f, fg, i)
|
||||||
|
// sequenceT
|
||||||
|
generateIOEitherSequenceT(f, fg, i)
|
||||||
|
// sequenceTuple
|
||||||
|
generateIOEitherSequenceTuple(f, fg, i)
|
||||||
|
// traverseTuple
|
||||||
|
generateIOEitherTraverseTuple(f, fg, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func IOEitherCommand() *C.Command {
|
||||||
|
return &C.Command{
|
||||||
|
Name: "ioeither",
|
||||||
|
Usage: "generate code for IOEither",
|
||||||
|
Flags: []C.Flag{
|
||||||
|
flagCount,
|
||||||
|
flagFilename,
|
||||||
|
},
|
||||||
|
Action: func(ctx *C.Context) error {
|
||||||
|
return generateIOEitherHelpers(
|
||||||
|
ctx.String(keyFilename),
|
||||||
|
ctx.Int(keyCount),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
137
cli/iooption.go
Normal file
137
cli/iooption.go
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
// 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 cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
A "github.com/IBM/fp-go/array"
|
||||||
|
C "github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func nonGenericIOOption(param string) string {
|
||||||
|
return fmt.Sprintf("IOOption[%s]", param)
|
||||||
|
}
|
||||||
|
|
||||||
|
func genericIOOption(param string) string {
|
||||||
|
return fmt.Sprintf("func() O.Option[%s]", param)
|
||||||
|
}
|
||||||
|
|
||||||
|
var extrasIOOption = A.Empty[string]()
|
||||||
|
|
||||||
|
func generateIOOptionSequenceT(f, fg *os.File, i int) {
|
||||||
|
generateGenericSequenceT(nonGenericIOOption, genericIOOption, extrasIOOption)(f, fg, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateIOOptionSequenceTuple(f, fg *os.File, i int) {
|
||||||
|
generateGenericSequenceTuple(nonGenericIOOption, genericIOOption, extrasIOOption)(f, fg, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateIOOptionTraverseTuple(f, fg *os.File, i int) {
|
||||||
|
generateGenericTraverseTuple(nonGenericIOOption, genericIOOption, extrasIOOption)(f, fg, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateIOOptionHelpers(filename string, count int) error {
|
||||||
|
dir, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
absDir, err := filepath.Abs(dir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pkg := filepath.Base(absDir)
|
||||||
|
f, err := os.Create(filepath.Clean(filename))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
// construct subdirectory
|
||||||
|
genFilename := filepath.Join("generic", filename)
|
||||||
|
err = os.MkdirAll("generic", os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fg, err := os.Create(filepath.Clean(genFilename))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fg.Close()
|
||||||
|
|
||||||
|
// log
|
||||||
|
log.Printf("Generating code in [%s] for package [%s] with [%d] repetitions ...", filename, pkg, count)
|
||||||
|
|
||||||
|
// some header
|
||||||
|
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
||||||
|
fmt.Fprintln(f, "// This file was generated by robots at")
|
||||||
|
fmt.Fprintf(f, "// %s\n\n", time.Now())
|
||||||
|
|
||||||
|
fmt.Fprintf(f, "package %s\n\n", pkg)
|
||||||
|
|
||||||
|
fmt.Fprintf(f, `
|
||||||
|
import (
|
||||||
|
G "github.com/IBM/fp-go/%s/generic"
|
||||||
|
T "github.com/IBM/fp-go/tuple"
|
||||||
|
)
|
||||||
|
`, pkg)
|
||||||
|
|
||||||
|
// some header
|
||||||
|
fmt.Fprintln(fg, "// Code generated by go generate; DO NOT EDIT.")
|
||||||
|
fmt.Fprintln(fg, "// This file was generated by robots at")
|
||||||
|
fmt.Fprintf(fg, "// %s\n", time.Now())
|
||||||
|
|
||||||
|
fmt.Fprintf(fg, "package generic\n\n")
|
||||||
|
|
||||||
|
fmt.Fprintf(fg, `
|
||||||
|
import (
|
||||||
|
T "github.com/IBM/fp-go/tuple"
|
||||||
|
O "github.com/IBM/fp-go/option"
|
||||||
|
A "github.com/IBM/fp-go/internal/apply"
|
||||||
|
)
|
||||||
|
`)
|
||||||
|
|
||||||
|
for i := 1; i <= count; i++ {
|
||||||
|
// sequenceT
|
||||||
|
generateIOOptionSequenceT(f, fg, i)
|
||||||
|
// sequenceTuple
|
||||||
|
generateIOOptionSequenceTuple(f, fg, i)
|
||||||
|
// traverseTuple
|
||||||
|
generateIOOptionTraverseTuple(f, fg, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func IOOptionCommand() *C.Command {
|
||||||
|
return &C.Command{
|
||||||
|
Name: "iooption",
|
||||||
|
Usage: "generate code for IOOption",
|
||||||
|
Flags: []C.Flag{
|
||||||
|
flagCount,
|
||||||
|
flagFilename,
|
||||||
|
},
|
||||||
|
Action: func(ctx *C.Context) error {
|
||||||
|
return generateIOOptionHelpers(
|
||||||
|
ctx.String(keyFilename),
|
||||||
|
ctx.Int(keyCount),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
47
cli/monad.go
47
cli/monad.go
@@ -1,3 +1,18 @@
|
|||||||
|
// 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 cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -6,18 +21,20 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func tupleType(i int) string {
|
func tupleType(name string) func(i int) string {
|
||||||
var buf strings.Builder
|
return func(i int) string {
|
||||||
buf.WriteString(fmt.Sprintf("T.Tuple%d[", i))
|
var buf strings.Builder
|
||||||
for j := 0; j < i; j++ {
|
buf.WriteString(fmt.Sprintf("T.Tuple%d[", i))
|
||||||
if j > 0 {
|
for j := 0; j < i; j++ {
|
||||||
buf.WriteString(", ")
|
if j > 0 {
|
||||||
|
buf.WriteString(", ")
|
||||||
|
}
|
||||||
|
buf.WriteString(fmt.Sprintf("%s%d", name, j+1))
|
||||||
}
|
}
|
||||||
buf.WriteString(fmt.Sprintf("T%d", j+1))
|
buf.WriteString("]")
|
||||||
}
|
|
||||||
buf.WriteString("]")
|
|
||||||
|
|
||||||
return buf.String()
|
return buf.String()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func monadGenerateSequenceTNonGeneric(
|
func monadGenerateSequenceTNonGeneric(
|
||||||
@@ -27,7 +44,7 @@ func monadGenerateSequenceTNonGeneric(
|
|||||||
) func(f *os.File, i int) {
|
) func(f *os.File, i int) {
|
||||||
return func(f *os.File, i int) {
|
return func(f *os.File, i int) {
|
||||||
|
|
||||||
tuple := tupleType(i)
|
tuple := tupleType("T")(i)
|
||||||
|
|
||||||
fmt.Fprintf(f, "SequenceT%d[", i)
|
fmt.Fprintf(f, "SequenceT%d[", i)
|
||||||
for j := 0; j < i; j++ {
|
for j := 0; j < i; j++ {
|
||||||
@@ -80,7 +97,7 @@ func monadGenerateSequenceTGeneric(
|
|||||||
) func(f *os.File, i int) {
|
) func(f *os.File, i int) {
|
||||||
return func(f *os.File, i int) {
|
return func(f *os.File, i int) {
|
||||||
|
|
||||||
tuple := tupleType(i)
|
tuple := tupleType("T")(i)
|
||||||
|
|
||||||
fmt.Fprintf(f, "SequenceT%d[", i)
|
fmt.Fprintf(f, "SequenceT%d[", i)
|
||||||
for j := 0; j < i; j++ {
|
for j := 0; j < i; j++ {
|
||||||
@@ -131,7 +148,7 @@ func generateTraverseTuple1(
|
|||||||
infix string) func(f *os.File, i int) {
|
infix string) func(f *os.File, i int) {
|
||||||
|
|
||||||
return func(f *os.File, i int) {
|
return func(f *os.File, i int) {
|
||||||
tuple := tupleType(i)
|
tuple := tupleType("T")(i)
|
||||||
|
|
||||||
fmt.Fprintf(f, "\n// TraverseTuple%d converts a [Tuple%d] of [A] via transformation functions transforming [A] to [%s] into a [%s].\n", i, i, hkt("A"), hkt(fmt.Sprintf("Tuple%d", i)))
|
fmt.Fprintf(f, "\n// TraverseTuple%d converts a [Tuple%d] of [A] via transformation functions transforming [A] to [%s] into a [%s].\n", i, i, hkt("A"), hkt(fmt.Sprintf("Tuple%d", i)))
|
||||||
fmt.Fprintf(f, "func TraverseTuple%d[", i)
|
fmt.Fprintf(f, "func TraverseTuple%d[", i)
|
||||||
@@ -218,7 +235,7 @@ func generateSequenceTuple1(
|
|||||||
|
|
||||||
return func(f *os.File, i int) {
|
return func(f *os.File, i int) {
|
||||||
|
|
||||||
tuple := tupleType(i)
|
tuple := tupleType("T")(i)
|
||||||
|
|
||||||
fmt.Fprintf(f, "\n// SequenceTuple%d converts a [Tuple%d] of [%s] into an [%s].\n", i, i, hkt("T"), hkt(fmt.Sprintf("Tuple%d", i)))
|
fmt.Fprintf(f, "\n// SequenceTuple%d converts a [Tuple%d] of [%s] into an [%s].\n", i, i, hkt("T"), hkt(fmt.Sprintf("Tuple%d", i)))
|
||||||
fmt.Fprintf(f, "func SequenceTuple%d[", i)
|
fmt.Fprintf(f, "func SequenceTuple%d[", i)
|
||||||
@@ -281,7 +298,7 @@ func generateSequenceT1(
|
|||||||
|
|
||||||
return func(f *os.File, i int) {
|
return func(f *os.File, i int) {
|
||||||
|
|
||||||
tuple := tupleType(i)
|
tuple := tupleType("T")(i)
|
||||||
|
|
||||||
fmt.Fprintf(f, "\n// SequenceT%d converts %d parameters of [%s] into a [%s].\n", i, i, hkt("T"), hkt(fmt.Sprintf("Tuple%d", i)))
|
fmt.Fprintf(f, "\n// SequenceT%d converts %d parameters of [%s] into a [%s].\n", i, i, hkt("T"), hkt(fmt.Sprintf("Tuple%d", i)))
|
||||||
fmt.Fprintf(f, "func SequenceT%d[", i)
|
fmt.Fprintf(f, "func SequenceT%d[", i)
|
||||||
|
284
cli/monad2.go
Normal file
284
cli/monad2.go
Normal file
@@ -0,0 +1,284 @@
|
|||||||
|
// 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 cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
A "github.com/IBM/fp-go/array"
|
||||||
|
F "github.com/IBM/fp-go/function"
|
||||||
|
N "github.com/IBM/fp-go/number"
|
||||||
|
S "github.com/IBM/fp-go/string"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
concStrgs = A.Monoid[string]().Concat
|
||||||
|
intercalStrgs = A.Intercalate(S.Monoid)
|
||||||
|
concAllStrgs = A.ConcatAll(A.Monoid[string]())
|
||||||
|
)
|
||||||
|
|
||||||
|
func joinAll(middle string) func(all ...[]string) string {
|
||||||
|
ic := intercalStrgs(middle)
|
||||||
|
return func(all ...[]string) string {
|
||||||
|
return ic(concAllStrgs(all))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateGenericSequenceT(
|
||||||
|
nonGenericType func(string) string,
|
||||||
|
genericType func(string) string,
|
||||||
|
extra []string,
|
||||||
|
) func(f, fg *os.File, i int) {
|
||||||
|
return func(f, fg *os.File, i int) {
|
||||||
|
// tuple
|
||||||
|
tuple := tupleType("T")(i)
|
||||||
|
// all types T
|
||||||
|
typesT := A.MakeBy(i, F.Flow2(
|
||||||
|
N.Inc[int],
|
||||||
|
S.Format[int]("T%d"),
|
||||||
|
))
|
||||||
|
// non generic version
|
||||||
|
fmt.Fprintf(f, "\n// SequenceT%d converts %d [%s] into a [%s]\n", i, i, nonGenericType("T"), nonGenericType(tuple))
|
||||||
|
fmt.Fprintf(f, "func SequenceT%d[%s any](\n", i, joinAll(", ")(extra, typesT))
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(f, " t%d %s,\n", j+1, nonGenericType(fmt.Sprintf("T%d", j+1)))
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, ") %s {\n", nonGenericType(tuple))
|
||||||
|
fmt.Fprintf(f, " return G.SequenceT%d[\n", i)
|
||||||
|
fmt.Fprintf(f, " %s,\n", nonGenericType(tuple))
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(f, " %s,\n", nonGenericType(fmt.Sprintf("T%d", j+1)))
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, " ](")
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "t%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, ")\n")
|
||||||
|
fmt.Fprintf(f, "}\n")
|
||||||
|
|
||||||
|
// generic version
|
||||||
|
fmt.Fprintf(fg, "\n// SequenceT%d converts %d [%s] into a [%s]\n", i, i, genericType("T"), genericType(tuple))
|
||||||
|
fmt.Fprintf(fg, "func SequenceT%d[\n", i)
|
||||||
|
fmt.Fprintf(fg, " G_TUPLE%d ~%s,\n", i, genericType(tuple))
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(fg, " G_T%d ~%s, \n", j+1, genericType(fmt.Sprintf("T%d", j+1)))
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, " %s any](\n", joinAll(", ")(extra, typesT))
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(fg, " t%d G_T%d,\n", j+1, j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, ") G_TUPLE%d {\n", i)
|
||||||
|
fmt.Fprintf(fg, " return A.SequenceT%d(\n", i)
|
||||||
|
// map call
|
||||||
|
var cio string
|
||||||
|
cb := generateNestedCallbacks(1, i)
|
||||||
|
if i > 1 {
|
||||||
|
cio = genericType(cb)
|
||||||
|
} else {
|
||||||
|
cio = fmt.Sprintf("G_TUPLE%d", i)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, " Map[%s],\n", joinAll(", ")(A.From("G_T1", cio), extra, A.From("T1", cb)))
|
||||||
|
// the apply calls
|
||||||
|
for j := 1; j < i; j++ {
|
||||||
|
if j < i-1 {
|
||||||
|
cb := generateNestedCallbacks(j+1, i)
|
||||||
|
cio = genericType(cb)
|
||||||
|
} else {
|
||||||
|
cio = fmt.Sprintf("G_TUPLE%d", i)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, " Ap[%s, %s, G_T%d],\n", cio, genericType(generateNestedCallbacks(j, i)), j+1)
|
||||||
|
}
|
||||||
|
// function parameters
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(fg, " t%d,\n", j+1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(fg, " )\n")
|
||||||
|
fmt.Fprintf(fg, "}\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateGenericSequenceTuple(
|
||||||
|
nonGenericType func(string) string,
|
||||||
|
genericType func(string) string,
|
||||||
|
extra []string,
|
||||||
|
) func(f, fg *os.File, i int) {
|
||||||
|
return func(f, fg *os.File, i int) {
|
||||||
|
// tuple
|
||||||
|
tuple := tupleType("T")(i)
|
||||||
|
// all types T
|
||||||
|
typesT := A.MakeBy(i, F.Flow2(
|
||||||
|
N.Inc[int],
|
||||||
|
S.Format[int]("T%d"),
|
||||||
|
))
|
||||||
|
// non generic version
|
||||||
|
fmt.Fprintf(f, "\n// SequenceTuple%d converts a [T.Tuple%d[%s]] into a [%s]\n", i, i, nonGenericType("T"), nonGenericType(tuple))
|
||||||
|
fmt.Fprintf(f, "func SequenceTuple%d[%s any](t T.Tuple%d[", i, joinAll(", ")(extra, typesT), i)
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "%s", nonGenericType(fmt.Sprintf("T%d", j+1)))
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "]) %s {\n", nonGenericType(tuple))
|
||||||
|
fmt.Fprintf(f, " return G.SequenceTuple%d[\n", i)
|
||||||
|
fmt.Fprintf(f, " %s,\n", nonGenericType(tuple))
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(f, " %s,\n", nonGenericType(fmt.Sprintf("T%d", j+1)))
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, " ](t)\n")
|
||||||
|
fmt.Fprintf(f, "}\n")
|
||||||
|
|
||||||
|
// generic version
|
||||||
|
fmt.Fprintf(fg, "\n// SequenceTuple%d converts a [T.Tuple%d[%s]] into a [%s]\n", i, i, genericType("T"), genericType(tuple))
|
||||||
|
fmt.Fprintf(fg, "func SequenceTuple%d[\n", i)
|
||||||
|
fmt.Fprintf(fg, " G_TUPLE%d ~%s,\n", i, genericType(tuple))
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(fg, " G_T%d ~%s, \n", j+1, genericType(fmt.Sprintf("T%d", j+1)))
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, " %s any](t T.Tuple%d[", joinAll(", ")(extra, typesT), i)
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(fg, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, "G_T%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, "]) G_TUPLE%d {\n", i)
|
||||||
|
fmt.Fprintf(fg, " return A.SequenceTuple%d(\n", i)
|
||||||
|
// map call
|
||||||
|
var cio string
|
||||||
|
cb := generateNestedCallbacks(1, i)
|
||||||
|
if i > 1 {
|
||||||
|
cio = genericType(cb)
|
||||||
|
} else {
|
||||||
|
cio = fmt.Sprintf("G_TUPLE%d", i)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, " Map[%s],\n", joinAll(", ")(A.From("G_T1", cio), extra, A.From("T1", cb)))
|
||||||
|
// the apply calls
|
||||||
|
for j := 1; j < i; j++ {
|
||||||
|
if j < i-1 {
|
||||||
|
cb := generateNestedCallbacks(j+1, i)
|
||||||
|
cio = genericType(cb)
|
||||||
|
} else {
|
||||||
|
cio = fmt.Sprintf("G_TUPLE%d", i)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, " Ap[%s, %s, G_T%d],\n", cio, genericType(generateNestedCallbacks(j, i)), j+1)
|
||||||
|
}
|
||||||
|
// function parameters
|
||||||
|
fmt.Fprintf(fg, " t)\n")
|
||||||
|
fmt.Fprintf(fg, "}\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateGenericTraverseTuple(
|
||||||
|
nonGenericType func(string) string,
|
||||||
|
genericType func(string) string,
|
||||||
|
extra []string,
|
||||||
|
) func(f, fg *os.File, i int) {
|
||||||
|
return func(f, fg *os.File, i int) {
|
||||||
|
// tuple
|
||||||
|
tupleT := tupleType("T")(i)
|
||||||
|
tupleA := tupleType("A")(i)
|
||||||
|
// all types T
|
||||||
|
typesT := A.MakeBy(i, F.Flow2(
|
||||||
|
N.Inc[int],
|
||||||
|
S.Format[int]("T%d"),
|
||||||
|
))
|
||||||
|
// all types A
|
||||||
|
typesA := A.MakeBy(i, F.Flow2(
|
||||||
|
N.Inc[int],
|
||||||
|
S.Format[int]("A%d"),
|
||||||
|
))
|
||||||
|
// all function types
|
||||||
|
typesF := A.MakeBy(i, F.Flow2(
|
||||||
|
N.Inc[int],
|
||||||
|
func(j int) string {
|
||||||
|
return fmt.Sprintf("F%d ~func(A%d) %s", j, j, nonGenericType(fmt.Sprintf("T%d", j)))
|
||||||
|
},
|
||||||
|
))
|
||||||
|
// non generic version
|
||||||
|
fmt.Fprintf(f, "\n// TraverseTuple%d converts a [T.Tuple%d[%s]] into a [%s]\n", i, i, nonGenericType("T"), nonGenericType(tupleT))
|
||||||
|
fmt.Fprintf(f, "func TraverseTuple%d[%s any](", i, joinAll(", ")(typesF, extra, typesA, typesT))
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "f%d F%d", j+1, j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, ") func(%s) %s {\n", tupleA, nonGenericType(tupleT))
|
||||||
|
fmt.Fprintf(f, " return G.TraverseTuple%d[%s](", i, nonGenericType(tupleT))
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "f%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, ")\n")
|
||||||
|
fmt.Fprintf(f, "}\n")
|
||||||
|
|
||||||
|
// generic version
|
||||||
|
fmt.Fprintf(fg, "\n// TraverseTuple%d converts a [T.Tuple%d[%s]] into a [%s]\n", i, i, genericType("T"), genericType(tupleT))
|
||||||
|
fmt.Fprintf(fg, "func TraverseTuple%d[\n", i)
|
||||||
|
fmt.Fprintf(fg, " G_TUPLE%d ~%s,\n", i, genericType(tupleT))
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(fg, " F%d ~func(A%d) G_T%d,\n", j+1, j+1, j+1)
|
||||||
|
}
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(fg, " G_T%d ~%s, \n", j+1, genericType(fmt.Sprintf("T%d", j+1)))
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, " %s any](", joinAll(", ")(extra, typesA, typesT))
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(fg, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, "f%d F%d", j+1, j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, ") func(%s) G_TUPLE%d {\n", tupleA, i)
|
||||||
|
fmt.Fprintf(fg, " return func(t %s) G_TUPLE%d {\n", tupleA, i)
|
||||||
|
fmt.Fprintf(fg, " return A.TraverseTuple%d(\n", i)
|
||||||
|
// map call
|
||||||
|
var cio string
|
||||||
|
cb := generateNestedCallbacks(1, i)
|
||||||
|
if i > 1 {
|
||||||
|
cio = genericType(cb)
|
||||||
|
} else {
|
||||||
|
cio = fmt.Sprintf("G_TUPLE%d", i)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, " Map[%s],\n", joinAll(", ")(A.From("G_T1", cio), extra, A.From("T1", cb)))
|
||||||
|
// the apply calls
|
||||||
|
for j := 1; j < i; j++ {
|
||||||
|
if j < i-1 {
|
||||||
|
cb := generateNestedCallbacks(j+1, i)
|
||||||
|
cio = genericType(cb)
|
||||||
|
} else {
|
||||||
|
cio = fmt.Sprintf("G_TUPLE%d", i)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fg, " Ap[%s, %s, G_T%d],\n", cio, genericType(generateNestedCallbacks(j, i)), j+1)
|
||||||
|
}
|
||||||
|
// function parameters
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
fmt.Fprintf(fg, " f%d,\n", j+1)
|
||||||
|
}
|
||||||
|
// tuple parameter
|
||||||
|
fmt.Fprintf(fg, " t)\n")
|
||||||
|
fmt.Fprintf(fg, " }\n")
|
||||||
|
fmt.Fprintf(fg, "}\n")
|
||||||
|
}
|
||||||
|
}
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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 cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -133,7 +148,7 @@ func generateOptionHelpers(filename string, count int) error {
|
|||||||
// some header
|
// some header
|
||||||
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
||||||
fmt.Fprintln(f, "// This file was generated by robots at")
|
fmt.Fprintln(f, "// This file was generated by robots at")
|
||||||
fmt.Fprintf(f, "// %s\n", time.Now())
|
fmt.Fprintf(f, "// %s\n\n", time.Now())
|
||||||
|
|
||||||
fmt.Fprintf(f, "package %s\n\n", pkg)
|
fmt.Fprintf(f, "package %s\n\n", pkg)
|
||||||
|
|
||||||
|
59
cli/pipe.go
59
cli/pipe.go
@@ -1,3 +1,18 @@
|
|||||||
|
// 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 cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -10,6 +25,40 @@ import (
|
|||||||
C "github.com/urfave/cli/v2"
|
C "github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func generateUnsliced(f *os.File, i int) {
|
||||||
|
// Create the optionize version
|
||||||
|
fmt.Fprintf(f, "\n// Unsliced%d converts a function taking a slice parameter into a function with %d parameters\n", i, i)
|
||||||
|
fmt.Fprintf(f, "func Unsliced%d[F ~func([]T) R, T, R any](f F) func(", i)
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "T")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, ") R {\n")
|
||||||
|
fmt.Fprintf(f, " return func(")
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "t%d", j+1)
|
||||||
|
}
|
||||||
|
if i > 0 {
|
||||||
|
fmt.Fprintf(f, " T")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, ") R {\n")
|
||||||
|
fmt.Fprintf(f, " return f([]T{")
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "t%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintln(f, "})")
|
||||||
|
fmt.Fprintln(f, " }")
|
||||||
|
fmt.Fprintln(f, "}")
|
||||||
|
}
|
||||||
|
|
||||||
func generateVariadic(f *os.File, i int) {
|
func generateVariadic(f *os.File, i int) {
|
||||||
// Create the nullary version
|
// Create the nullary version
|
||||||
fmt.Fprintf(f, "\n// Variadic%d converts a function taking %d parameters and a final slice into a function with %d parameters but a final variadic argument\n", i, i, i)
|
fmt.Fprintf(f, "\n// Variadic%d converts a function taking %d parameters and a final slice into a function with %d parameters but a final variadic argument\n", i, i, i)
|
||||||
@@ -68,7 +117,7 @@ func generateVariadic(f *os.File, i int) {
|
|||||||
fmt.Fprintf(f, "v)\n")
|
fmt.Fprintf(f, "v)\n")
|
||||||
fmt.Fprintf(f, " }\n")
|
fmt.Fprintf(f, " }\n")
|
||||||
|
|
||||||
fmt.Fprintf(f, "}")
|
fmt.Fprintf(f, "}\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateUnvariadic(f *os.File, i int) {
|
func generateUnvariadic(f *os.File, i int) {
|
||||||
@@ -129,7 +178,7 @@ func generateUnvariadic(f *os.File, i int) {
|
|||||||
fmt.Fprintf(f, "v...)\n")
|
fmt.Fprintf(f, "v...)\n")
|
||||||
fmt.Fprintf(f, " }\n")
|
fmt.Fprintf(f, " }\n")
|
||||||
|
|
||||||
fmt.Fprintf(f, "}")
|
fmt.Fprintf(f, "}\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateNullary(f *os.File, i int) {
|
func generateNullary(f *os.File, i int) {
|
||||||
@@ -322,7 +371,7 @@ func generatePipeHelpers(filename string, count int) error {
|
|||||||
// some header
|
// some header
|
||||||
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
||||||
fmt.Fprintln(f, "// This file was generated by robots at")
|
fmt.Fprintln(f, "// This file was generated by robots at")
|
||||||
fmt.Fprintf(f, "// %s\n", time.Now())
|
fmt.Fprintf(f, "// %s\n\n", time.Now())
|
||||||
|
|
||||||
fmt.Fprintf(f, "package %s\n", pkg)
|
fmt.Fprintf(f, "package %s\n", pkg)
|
||||||
|
|
||||||
@@ -332,6 +381,8 @@ func generatePipeHelpers(filename string, count int) error {
|
|||||||
generateVariadic(f, 0)
|
generateVariadic(f, 0)
|
||||||
// unvariadic
|
// unvariadic
|
||||||
generateUnvariadic(f, 0)
|
generateUnvariadic(f, 0)
|
||||||
|
// unsliced
|
||||||
|
generateUnsliced(f, 0)
|
||||||
|
|
||||||
for i := 1; i <= count; i++ {
|
for i := 1; i <= count; i++ {
|
||||||
|
|
||||||
@@ -349,6 +400,8 @@ func generatePipeHelpers(filename string, count int) error {
|
|||||||
generateVariadic(f, i)
|
generateVariadic(f, i)
|
||||||
// unvariadic
|
// unvariadic
|
||||||
generateUnvariadic(f, i)
|
generateUnvariadic(f, i)
|
||||||
|
// unsliced
|
||||||
|
generateUnsliced(f, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -117,7 +118,7 @@ func generateReaderHelpers(filename string, count int) error {
|
|||||||
// some header
|
// some header
|
||||||
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
||||||
fmt.Fprintln(f, "// This file was generated by robots at")
|
fmt.Fprintln(f, "// This file was generated by robots at")
|
||||||
fmt.Fprintf(f, "// %s\n", time.Now())
|
fmt.Fprintf(f, "// %s\n\n", time.Now())
|
||||||
|
|
||||||
fmt.Fprintf(f, "package %s\n\n", pkg)
|
fmt.Fprintf(f, "package %s\n\n", pkg)
|
||||||
|
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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 cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -154,7 +169,7 @@ func generateReaderIOEitherHelpers(filename string, count int) error {
|
|||||||
// some header
|
// some header
|
||||||
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
||||||
fmt.Fprintln(f, "// This file was generated by robots at")
|
fmt.Fprintln(f, "// This file was generated by robots at")
|
||||||
fmt.Fprintf(f, "// %s\n", time.Now())
|
fmt.Fprintf(f, "// %s\n\n", time.Now())
|
||||||
|
|
||||||
fmt.Fprintf(f, "package %s\n\n", pkg)
|
fmt.Fprintf(f, "package %s\n\n", pkg)
|
||||||
|
|
||||||
|
265
cli/tuple.go
265
cli/tuple.go
@@ -1,3 +1,18 @@
|
|||||||
|
// 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 cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -5,6 +20,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
C "github.com/urfave/cli/v2"
|
C "github.com/urfave/cli/v2"
|
||||||
@@ -21,8 +37,51 @@ func writeTupleType(f *os.File, symbol string, i int) {
|
|||||||
fmt.Fprintf(f, "]")
|
fmt.Fprintf(f, "]")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeTupleType(name string) func(i int) string {
|
||||||
|
return func(i int) string {
|
||||||
|
var buf strings.Builder
|
||||||
|
buf.WriteString(fmt.Sprintf("Tuple%d[", i))
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
buf.WriteString(", ")
|
||||||
|
}
|
||||||
|
buf.WriteString(fmt.Sprintf("%s%d", name, j+1))
|
||||||
|
}
|
||||||
|
buf.WriteString("]")
|
||||||
|
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func generatePush(f *os.File, i int) {
|
||||||
|
tuple1 := makeTupleType("T")(i)
|
||||||
|
tuple2 := makeTupleType("T")(i + 1)
|
||||||
|
// Create the replicate version
|
||||||
|
fmt.Fprintf(f, "\n// Push%d creates a [Tuple%d] from a [Tuple%d] by appending a constant value\n", i, i+1, i)
|
||||||
|
fmt.Fprintf(f, "func Push%d[", i)
|
||||||
|
// function prototypes
|
||||||
|
for j := 0; j <= i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "T%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, " any](value T%d) func(%s) %s {\n", i+1, tuple1, tuple2)
|
||||||
|
fmt.Fprintf(f, " return func(t %s) %s {\n", tuple1, tuple2)
|
||||||
|
fmt.Fprintf(f, " return MakeTuple%d(", i+1)
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "t.F%d", j+1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, ", value)\n")
|
||||||
|
fmt.Fprintf(f, " }\n")
|
||||||
|
fmt.Fprintf(f, "}\n")
|
||||||
|
}
|
||||||
|
|
||||||
func generateReplicate(f *os.File, i int) {
|
func generateReplicate(f *os.File, i int) {
|
||||||
// Create the optionize version
|
// Create the replicate version
|
||||||
fmt.Fprintf(f, "\n// Replicate%d creates a [Tuple%d] with all fields set to the input value `t`\n", i, i)
|
fmt.Fprintf(f, "\n// Replicate%d creates a [Tuple%d] with all fields set to the input value `t`\n", i, i)
|
||||||
fmt.Fprintf(f, "func Replicate%d[T any](t T) Tuple%d[", i, i)
|
fmt.Fprintf(f, "func Replicate%d[T any](t T) Tuple%d[", i, i)
|
||||||
for j := 1; j <= i; j++ {
|
for j := 1; j <= i; j++ {
|
||||||
@@ -279,7 +338,7 @@ func generateUntupled(f *os.File, i int) {
|
|||||||
|
|
||||||
func generateTupled(f *os.File, i int) {
|
func generateTupled(f *os.File, i int) {
|
||||||
// Create the optionize version
|
// Create the optionize version
|
||||||
fmt.Fprintf(f, "\n// Tupled%d converts a function with %d parameters returning into a function taking a Tuple%d\n// The inverse function is [Untupled%d]\n", i, i, i, i)
|
fmt.Fprintf(f, "\n// Tupled%d converts a function with %d parameters into a function taking a Tuple%d\n// The inverse function is [Untupled%d]\n", i, i, i, i)
|
||||||
fmt.Fprintf(f, "func Tupled%d[F ~func(", i)
|
fmt.Fprintf(f, "func Tupled%d[F ~func(", i)
|
||||||
for j := 0; j < i; j++ {
|
for j := 0; j < i; j++ {
|
||||||
if j > 0 {
|
if j > 0 {
|
||||||
@@ -340,14 +399,16 @@ func generateTupleHelpers(filename string, count int) error {
|
|||||||
// some header
|
// some header
|
||||||
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
fmt.Fprintln(f, "// Code generated by go generate; DO NOT EDIT.")
|
||||||
fmt.Fprintln(f, "// This file was generated by robots at")
|
fmt.Fprintln(f, "// This file was generated by robots at")
|
||||||
fmt.Fprintf(f, "// %s\n", time.Now())
|
fmt.Fprintf(f, "// %s\n\n", time.Now())
|
||||||
|
|
||||||
fmt.Fprintf(f, "package %s\n\n", pkg)
|
fmt.Fprintf(f, "package %s\n\n", pkg)
|
||||||
|
|
||||||
fmt.Fprintf(f, `
|
fmt.Fprintf(f, `
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"encoding/json"
|
||||||
M "github.com/IBM/fp-go/monoid"
|
M "github.com/IBM/fp-go/monoid"
|
||||||
O "github.com/IBM/fp-go/ord"
|
O "github.com/IBM/fp-go/ord"
|
||||||
)
|
)
|
||||||
`)
|
`)
|
||||||
|
|
||||||
@@ -371,11 +432,207 @@ import (
|
|||||||
generateMap(f, i)
|
generateMap(f, i)
|
||||||
// generate replicate
|
// generate replicate
|
||||||
generateReplicate(f, i)
|
generateReplicate(f, i)
|
||||||
|
// generate tuple functions such as string and fmt
|
||||||
|
generateTupleString(f, i)
|
||||||
|
// generate json support
|
||||||
|
generateTupleMarshal(f, i)
|
||||||
|
// generate json support
|
||||||
|
generateTupleUnmarshal(f, i)
|
||||||
|
// generate toArray
|
||||||
|
generateToArray(f, i)
|
||||||
|
// generate fromArray
|
||||||
|
generateFromArray(f, i)
|
||||||
|
// generate push
|
||||||
|
if i < count {
|
||||||
|
generatePush(f, i)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func generateTupleMarshal(f *os.File, i int) {
|
||||||
|
// Create the stringify version
|
||||||
|
fmt.Fprintf(f, "\n// MarshalJSON marshals the [Tuple%d] into a JSON array\n", i)
|
||||||
|
fmt.Fprintf(f, "func (t ")
|
||||||
|
writeTupleType(f, "T", i)
|
||||||
|
fmt.Fprintf(f, ") MarshalJSON() ([]byte, error) {\n")
|
||||||
|
fmt.Fprintf(f, " return json.Marshal([]any{")
|
||||||
|
// function prototypes
|
||||||
|
for j := 1; j <= i; j++ {
|
||||||
|
if j > 1 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "t.F%d", j)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "})\n")
|
||||||
|
fmt.Fprintf(f, "}\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateTupleUnmarshal(f *os.File, i int) {
|
||||||
|
// Create the stringify version
|
||||||
|
fmt.Fprintf(f, "\n// UnmarshalJSON unmarshals a JSON array into a [Tuple%d]\n", i)
|
||||||
|
fmt.Fprintf(f, "func (t *")
|
||||||
|
writeTupleType(f, "T", i)
|
||||||
|
fmt.Fprintf(f, ") UnmarshalJSON(data []byte) error {\n")
|
||||||
|
fmt.Fprintf(f, " var tmp []json.RawMessage\n")
|
||||||
|
fmt.Fprintf(f, " if err := json.Unmarshal(data, &tmp); err != nil {return err}\n")
|
||||||
|
fmt.Fprintf(f, " l := len(tmp)\n")
|
||||||
|
// unmarshal fields
|
||||||
|
for j := 1; j <= i; j++ {
|
||||||
|
fmt.Fprintf(f, " if l > %d {\n", j-1)
|
||||||
|
fmt.Fprintf(f, " if err := json.Unmarshal(tmp[%d], &t.F%d); err != nil {return err}\n", j-1, j)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, " ")
|
||||||
|
for j := 1; j <= i; j++ {
|
||||||
|
fmt.Fprintf(f, "}")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "\n return nil\n")
|
||||||
|
fmt.Fprintf(f, "}\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateToArray(f *os.File, i int) {
|
||||||
|
// Create the stringify version
|
||||||
|
fmt.Fprintf(f, "\n// ToArray converts the [Tuple%d] into an array of type [R] using %d transformation functions from [T] to [R]\n// The inverse function is [FromArray%d]\n", i, i, i)
|
||||||
|
fmt.Fprintf(f, "func ToArray%d[", i)
|
||||||
|
// function prototypes
|
||||||
|
for j := 1; j <= i; j++ {
|
||||||
|
if j > 1 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "F%d ~func(T%d) R", j, j)
|
||||||
|
}
|
||||||
|
for j := 1; j <= i; j++ {
|
||||||
|
fmt.Fprintf(f, ", T%d", j)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, ", R any](")
|
||||||
|
for j := 1; j <= i; j++ {
|
||||||
|
if j > 1 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "f%d F%d", j, j)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, ") func(t ")
|
||||||
|
writeTupleType(f, "T", i)
|
||||||
|
fmt.Fprintf(f, ") []R {\n")
|
||||||
|
fmt.Fprintf(f, " return func(t ")
|
||||||
|
writeTupleType(f, "T", i)
|
||||||
|
fmt.Fprintf(f, ") []R {\n")
|
||||||
|
fmt.Fprintf(f, " return []R{\n")
|
||||||
|
for j := 1; j <= i; j++ {
|
||||||
|
fmt.Fprintf(f, " f%d(t.F%d),\n", j, j)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, " }\n")
|
||||||
|
fmt.Fprintf(f, " }\n")
|
||||||
|
fmt.Fprintf(f, "}\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateFromArray(f *os.File, i int) {
|
||||||
|
// Create the stringify version
|
||||||
|
fmt.Fprintf(f, "\n// FromArray converts an array of [R] into a [Tuple%d] using %d functions from [R] to [T]\n// The inverse function is [ToArray%d]\n", i, i, i)
|
||||||
|
fmt.Fprintf(f, "func FromArray%d[", i)
|
||||||
|
// function prototypes
|
||||||
|
for j := 1; j <= i; j++ {
|
||||||
|
if j > 1 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "F%d ~func(R) T%d", j, j)
|
||||||
|
}
|
||||||
|
for j := 1; j <= i; j++ {
|
||||||
|
fmt.Fprintf(f, ", T%d", j)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, ", R any](")
|
||||||
|
for j := 1; j <= i; j++ {
|
||||||
|
if j > 1 {
|
||||||
|
fmt.Fprintf(f, ", ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, "f%d F%d", j, j)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, ") func(r []R) ")
|
||||||
|
writeTupleType(f, "T", i)
|
||||||
|
fmt.Fprintf(f, " {\n")
|
||||||
|
fmt.Fprintf(f, " return func(r []R) ")
|
||||||
|
writeTupleType(f, "T", i)
|
||||||
|
fmt.Fprintf(f, " {\n")
|
||||||
|
fmt.Fprintf(f, " return MakeTuple%d(\n", i)
|
||||||
|
for j := 1; j <= i; j++ {
|
||||||
|
fmt.Fprintf(f, " f%d(r[%d]),\n", j, j-1)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(f, " )\n")
|
||||||
|
fmt.Fprintf(f, " }\n")
|
||||||
|
fmt.Fprintf(f, "}\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateTupleString(f *os.File, i int) {
|
||||||
|
// Create the stringify version
|
||||||
|
fmt.Fprintf(f, "\n// String prints some debug info for the [Tuple%d]\n", i)
|
||||||
|
fmt.Fprintf(f, "func (t ")
|
||||||
|
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, ")\", ")
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
|
||||||
|
// func generateTupleJson(f *os.File, i int) {
|
||||||
|
// // Create the stringify version
|
||||||
|
// fmt.Fprintf(f, "\n// MarshalJSON converts the [Tuple%d] into a JSON byte stream\n", i)
|
||||||
|
// fmt.Fprintf(f, "func (t ")
|
||||||
|
// writeTupleType(f, "T", i)
|
||||||
|
// fmt.Fprintf(f, ") MarshalJSON() ([]byte, error) {\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, ")\", ")
|
||||||
|
// 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")
|
||||||
|
// }
|
||||||
|
|
||||||
func TupleCommand() *C.Command {
|
func TupleCommand() *C.Command {
|
||||||
return &C.Command{
|
return &C.Command{
|
||||||
Name: "tuple",
|
Name: "tuple",
|
||||||
|
59
constant/const.go
Normal file
59
constant/const.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 constant
|
||||||
|
|
||||||
|
import (
|
||||||
|
F "github.com/IBM/fp-go/function"
|
||||||
|
M "github.com/IBM/fp-go/monoid"
|
||||||
|
S "github.com/IBM/fp-go/semigroup"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Const[E, A any] struct {
|
||||||
|
value E
|
||||||
|
}
|
||||||
|
|
||||||
|
func Make[E, A any](e E) Const[E, A] {
|
||||||
|
return Const[E, A]{value: e}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Unwrap[E, A any](c Const[E, A]) E {
|
||||||
|
return c.value
|
||||||
|
}
|
||||||
|
|
||||||
|
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] {
|
||||||
|
return Make[E, B](fa.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MonadAp[E, A, B any](s S.Semigroup[E]) func(fab Const[E, func(A) B], fa Const[E, A]) Const[E, B] {
|
||||||
|
return func(fab Const[E, func(A) B], fa Const[E, A]) Const[E, B] {
|
||||||
|
return Make[E, B](s.Concat(fab.value, fa.value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Map[E, A, B any](f func(A) B) func(fa Const[E, A]) Const[E, B] {
|
||||||
|
return F.Bind2nd(MonadMap[E, A, B], f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Ap[E, A, B any](s S.Semigroup[E]) func(fa Const[E, A]) func(fab Const[E, func(A) B]) Const[E, B] {
|
||||||
|
monadap := MonadAp[E, A, B](s)
|
||||||
|
return func(fa Const[E, A]) func(fab Const[E, func(A) B]) Const[E, B] {
|
||||||
|
return F.Bind2nd(monadap, fa)
|
||||||
|
}
|
||||||
|
}
|
40
constant/const_test.go
Normal file
40
constant/const_test.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
// 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 constant
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
F "github.com/IBM/fp-go/function"
|
||||||
|
"github.com/IBM/fp-go/internal/utils"
|
||||||
|
S "github.com/IBM/fp-go/string"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMap(t *testing.T) {
|
||||||
|
fa := Make[string, int]("foo")
|
||||||
|
assert.Equal(t, fa, F.Pipe1(fa, Map[string, int](utils.Double)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOf(t *testing.T) {
|
||||||
|
assert.Equal(t, Make[string, int](""), Of[string, int](S.Monoid)(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAp(t *testing.T) {
|
||||||
|
fab := Make[string, int]("bar")
|
||||||
|
assert.Equal(t, Make[string, int]("foobar"), Ap[string, int, int](S.Monoid)(fab)(Make[string, func(int) int]("foo")))
|
||||||
|
}
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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 constraints
|
package constraints
|
||||||
|
|
||||||
type Ordered interface {
|
type Ordered interface {
|
||||||
@@ -19,3 +34,7 @@ type Integer interface {
|
|||||||
type Float interface {
|
type Float interface {
|
||||||
~float32 | ~float64
|
~float32 | ~float64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Complex interface {
|
||||||
|
~complex64 | ~complex128
|
||||||
|
}
|
||||||
|
@@ -13,5 +13,5 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
// Package context contains versions of monads that work with a golang [context.Context]
|
// Package context contains versions of reader IO monads that work with a golang [context.Context]
|
||||||
package context
|
package context
|
||||||
|
@@ -1,18 +1,32 @@
|
|||||||
|
// 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
|
package generic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
E "github.com/IBM/fp-go/either"
|
E "github.com/IBM/fp-go/either"
|
||||||
ET "github.com/IBM/fp-go/either"
|
|
||||||
IOE "github.com/IBM/fp-go/ioeither/generic"
|
IOE "github.com/IBM/fp-go/ioeither/generic"
|
||||||
)
|
)
|
||||||
|
|
||||||
// withContext wraps an existing IOEither and performs a context check for cancellation before delegating
|
// WithContext wraps an existing IOEither and performs a context check for cancellation before delegating
|
||||||
func WithContext[GIO ~func() E.Either[error, A], A any](ctx context.Context, ma GIO) GIO {
|
func WithContext[GIO ~func() E.Either[error, A], A any](ctx context.Context, ma GIO) GIO {
|
||||||
return IOE.MakeIO[GIO](func() E.Either[error, A] {
|
return IOE.MakeIO[GIO](func() E.Either[error, A] {
|
||||||
if err := context.Cause(ctx); err != nil {
|
if err := context.Cause(ctx); err != nil {
|
||||||
return ET.Left[A](err)
|
return E.Left[A](err)
|
||||||
}
|
}
|
||||||
return ma()
|
return ma()
|
||||||
})
|
})
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// Copyright (c) 2023 IBM Corp.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package ioeither
|
package ioeither
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,53 +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 reader
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
R "github.com/IBM/fp-go/reader/generic"
|
|
||||||
)
|
|
||||||
|
|
||||||
// these functions curry a golang function with the context as the firsr parameter into a either reader with the context as the last parameter
|
|
||||||
// this goes back to the advice in https://pkg.go.dev/context to put the context as a first parameter as a convention
|
|
||||||
|
|
||||||
func Curry0[A any](f func(context.Context) A) Reader[A] {
|
|
||||||
return R.Curry0[Reader[A]](f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Curry1[T1, A any](f func(context.Context, T1) A) func(T1) Reader[A] {
|
|
||||||
return R.Curry1[Reader[A]](f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Curry2[T1, T2, A any](f func(context.Context, T1, T2) A) func(T1) func(T2) Reader[A] {
|
|
||||||
return R.Curry2[Reader[A]](f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Curry3[T1, T2, T3, A any](f func(context.Context, T1, T2, T3) A) func(T1) func(T2) func(T3) Reader[A] {
|
|
||||||
return R.Curry3[Reader[A]](f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Uncurry1[T1, A any](f func(T1) Reader[A]) func(context.Context, T1) A {
|
|
||||||
return R.Uncurry1(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Uncurry2[T1, T2, A any](f func(T1) func(T2) Reader[A]) func(context.Context, T1, T2) A {
|
|
||||||
return R.Uncurry2(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Uncurry3[T1, T2, T3, A any](f func(T1) func(T2) func(T3) Reader[A]) func(context.Context, T1, T2, T3) A {
|
|
||||||
return R.Uncurry3(f)
|
|
||||||
}
|
|
@@ -1,26 +0,0 @@
|
|||||||
package reader
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
R "github.com/IBM/fp-go/reader/generic"
|
|
||||||
)
|
|
||||||
|
|
||||||
// these functions curry a golang function with the context as the firsr parameter into a either reader with the context as the last parameter
|
|
||||||
// this goes back to the advice in https://pkg.go.dev/context to put the context as a first parameter as a convention
|
|
||||||
|
|
||||||
func From0[A any](f func(context.Context) A) func() Reader[A] {
|
|
||||||
return R.From0[Reader[A]](f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func From1[T1, A any](f func(context.Context, T1) A) func(T1) Reader[A] {
|
|
||||||
return R.From1[Reader[A]](f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func From2[T1, T2, A any](f func(context.Context, T1, T2) A) func(T1, T2) Reader[A] {
|
|
||||||
return R.From2[Reader[A]](f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func From3[T1, T2, T3, A any](f func(context.Context, T1, T2, T3) A) func(T1, T2, T3) Reader[A] {
|
|
||||||
return R.From3[Reader[A]](f)
|
|
||||||
}
|
|
@@ -1,43 +0,0 @@
|
|||||||
package reader
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
R "github.com/IBM/fp-go/reader/generic"
|
|
||||||
)
|
|
||||||
|
|
||||||
func MonadMap[A, B any](fa Reader[A], f func(A) B) Reader[B] {
|
|
||||||
return R.MonadMap[Reader[A], Reader[B]](fa, f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Map[A, B any](f func(A) B) func(Reader[A]) Reader[B] {
|
|
||||||
return R.Map[Reader[A], Reader[B]](f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func MonadChain[A, B any](ma Reader[A], f func(A) Reader[B]) Reader[B] {
|
|
||||||
return R.MonadChain(ma, f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Chain[A, B any](f func(A) Reader[B]) func(Reader[A]) Reader[B] {
|
|
||||||
return R.Chain[Reader[A]](f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Of[A any](a A) Reader[A] {
|
|
||||||
return R.Of[Reader[A]](a)
|
|
||||||
}
|
|
||||||
|
|
||||||
func MonadAp[A, B any](fab Reader[func(A) B], fa Reader[A]) Reader[B] {
|
|
||||||
return R.MonadAp[Reader[A], Reader[B]](fab, fa)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Ap[A, B any](fa Reader[A]) func(Reader[func(A) B]) Reader[B] {
|
|
||||||
return R.Ap[Reader[A], Reader[B], Reader[func(A) B]](fa)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Ask() Reader[context.Context] {
|
|
||||||
return R.Ask[Reader[context.Context]]()
|
|
||||||
}
|
|
||||||
|
|
||||||
func Asks[A any](r Reader[A]) Reader[A] {
|
|
||||||
return R.Asks(r)
|
|
||||||
}
|
|
@@ -1,60 +0,0 @@
|
|||||||
package reader
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
F "github.com/IBM/fp-go/function"
|
|
||||||
T "github.com/IBM/fp-go/tuple"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GoFunction(ctx context.Context, data string) string {
|
|
||||||
return strings.ToUpper(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func GoIntFunction(ctx context.Context, data string, number int) string {
|
|
||||||
return fmt.Sprintf("%s: %d", data, number)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReaderFrom(t *testing.T) {
|
|
||||||
ctx := context.Background()
|
|
||||||
f := From1(GoFunction)
|
|
||||||
|
|
||||||
result := f("input")(ctx)
|
|
||||||
|
|
||||||
assert.Equal(t, result, "INPUT")
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func MyFinalResult(left, right string) string {
|
|
||||||
return fmt.Sprintf("%s-%s", left, right)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReadersFrom(t *testing.T) {
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
f1 := From1(GoFunction)
|
|
||||||
f2 := From2(GoIntFunction)
|
|
||||||
|
|
||||||
result1 := f1("input")(ctx)
|
|
||||||
result2 := f2("input", 10)(ctx)
|
|
||||||
|
|
||||||
result3 := MyFinalResult(result1, result2)
|
|
||||||
|
|
||||||
h := F.Pipe1(
|
|
||||||
SequenceT2(f1("input"), f2("input", 10)),
|
|
||||||
Map(T.Tupled2(MyFinalResult)),
|
|
||||||
)
|
|
||||||
|
|
||||||
composedResult := h(ctx)
|
|
||||||
|
|
||||||
assert.Equal(t, result1, "INPUT")
|
|
||||||
assert.Equal(t, result2, "input: 10")
|
|
||||||
assert.Equal(t, result3, "INPUT-input: 10")
|
|
||||||
|
|
||||||
assert.Equal(t, composedResult, "INPUT-input: 10")
|
|
||||||
|
|
||||||
}
|
|
@@ -1,42 +0,0 @@
|
|||||||
package reader
|
|
||||||
|
|
||||||
import (
|
|
||||||
R "github.com/IBM/fp-go/reader/generic"
|
|
||||||
T "github.com/IBM/fp-go/tuple"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SequenceT converts n inputs of higher kinded types into a higher kinded types of n strongly typed values, represented as a tuple
|
|
||||||
|
|
||||||
func SequenceT1[A any](a Reader[A]) Reader[T.Tuple1[A]] {
|
|
||||||
return R.SequenceT1[
|
|
||||||
Reader[A],
|
|
||||||
Reader[T.Tuple1[A]],
|
|
||||||
](a)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SequenceT2[A, B any](a Reader[A], b Reader[B]) Reader[T.Tuple2[A, B]] {
|
|
||||||
return R.SequenceT2[
|
|
||||||
Reader[A],
|
|
||||||
Reader[B],
|
|
||||||
Reader[T.Tuple2[A, B]],
|
|
||||||
](a, b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SequenceT3[A, B, C any](a Reader[A], b Reader[B], c Reader[C]) Reader[T.Tuple3[A, B, C]] {
|
|
||||||
return R.SequenceT3[
|
|
||||||
Reader[A],
|
|
||||||
Reader[B],
|
|
||||||
Reader[C],
|
|
||||||
Reader[T.Tuple3[A, B, C]],
|
|
||||||
](a, b, c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SequenceT4[A, B, C, D any](a Reader[A], b Reader[B], c Reader[C], d Reader[D]) Reader[T.Tuple4[A, B, C, D]] {
|
|
||||||
return R.SequenceT4[
|
|
||||||
Reader[A],
|
|
||||||
Reader[B],
|
|
||||||
Reader[C],
|
|
||||||
Reader[D],
|
|
||||||
Reader[T.Tuple4[A, B, C, D]],
|
|
||||||
](a, b, c, d)
|
|
||||||
}
|
|
@@ -1,11 +0,0 @@
|
|||||||
// Package reader implements a specialization of the Reader monad assuming a golang context as the context of the monad
|
|
||||||
package reader
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
R "github.com/IBM/fp-go/reader"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Reader is a specialization of the Reader monad assuming a golang context as the context of the monad
|
|
||||||
type Reader[A any] R.Reader[context.Context, A]
|
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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
|
package readereither
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -9,6 +24,11 @@ func TraverseArray[A, B any](f func(A) ReaderEither[B]) func([]A) ReaderEither[[
|
|||||||
return RE.TraverseArray[ReaderEither[B], ReaderEither[[]B], []A](f)
|
return RE.TraverseArray[ReaderEither[B], ReaderEither[[]B], []A](f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TraverseArrayWithIndex transforms an array
|
||||||
|
func TraverseArrayWithIndex[A, B any](f func(int, A) ReaderEither[B]) func([]A) ReaderEither[[]B] {
|
||||||
|
return RE.TraverseArrayWithIndex[ReaderEither[B], ReaderEither[[]B], []A](f)
|
||||||
|
}
|
||||||
|
|
||||||
// SequenceArray converts a homogeneous sequence of either into an either of sequence
|
// SequenceArray converts a homogeneous sequence of either into an either of sequence
|
||||||
func SequenceArray[A any](ma []ReaderEither[A]) ReaderEither[[]A] {
|
func SequenceArray[A any](ma []ReaderEither[A]) ReaderEither[[]A] {
|
||||||
return RE.SequenceArray[ReaderEither[A], ReaderEither[[]A]](ma)
|
return RE.SequenceArray[ReaderEither[A], ReaderEither[[]A]](ma)
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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
|
package readereither
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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
|
package readereither
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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 exec
|
package exec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -19,8 +34,6 @@ var (
|
|||||||
|
|
||||||
func command(name string, args []string, in []byte) RE.ReaderEither[exec.CommandOutput] {
|
func command(name string, args []string, in []byte) RE.ReaderEither[exec.CommandOutput] {
|
||||||
return func(ctx context.Context) E.Either[error, exec.CommandOutput] {
|
return func(ctx context.Context) E.Either[error, exec.CommandOutput] {
|
||||||
return E.TryCatchError(func() (exec.CommandOutput, error) {
|
return E.TryCatchError(GE.Exec(ctx, name, args, in))
|
||||||
return GE.Exec(ctx, name, args, in)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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
|
package readereither
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,9 +1,23 @@
|
|||||||
|
// 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
|
package readereither
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
R "github.com/IBM/fp-go/context/reader"
|
|
||||||
ET "github.com/IBM/fp-go/either"
|
ET "github.com/IBM/fp-go/either"
|
||||||
O "github.com/IBM/fp-go/option"
|
O "github.com/IBM/fp-go/option"
|
||||||
RE "github.com/IBM/fp-go/readereither/generic"
|
RE "github.com/IBM/fp-go/readereither/generic"
|
||||||
@@ -17,14 +31,6 @@ func FromEither[A any](e ET.Either[error, A]) ReaderEither[A] {
|
|||||||
return RE.FromEither[ReaderEither[A]](e)
|
return RE.FromEither[ReaderEither[A]](e)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RightReader[A any](r R.Reader[A]) ReaderEither[A] {
|
|
||||||
return RE.RightReader[R.Reader[A], ReaderEither[A]](r)
|
|
||||||
}
|
|
||||||
|
|
||||||
func LeftReader[A any](l R.Reader[error]) ReaderEither[A] {
|
|
||||||
return RE.LeftReader[R.Reader[error], ReaderEither[A]](l)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Left[A any](l error) ReaderEither[A] {
|
func Left[A any](l error) ReaderEither[A] {
|
||||||
return RE.Left[ReaderEither[A]](l)
|
return RE.Left[ReaderEither[A]](l)
|
||||||
}
|
}
|
||||||
@@ -33,10 +39,6 @@ func Right[A any](r A) ReaderEither[A] {
|
|||||||
return RE.Right[ReaderEither[A]](r)
|
return RE.Right[ReaderEither[A]](r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FromReader[A any](r R.Reader[A]) ReaderEither[A] {
|
|
||||||
return RE.FromReader[R.Reader[A], ReaderEither[A]](r)
|
|
||||||
}
|
|
||||||
|
|
||||||
func MonadMap[A, B any](fa ReaderEither[A], f func(A) B) ReaderEither[B] {
|
func MonadMap[A, B any](fa ReaderEither[A], f func(A) B) ReaderEither[B] {
|
||||||
return RE.MonadMap[ReaderEither[A], ReaderEither[B]](fa, f)
|
return RE.MonadMap[ReaderEither[A], ReaderEither[B]](fa, f)
|
||||||
}
|
}
|
||||||
@@ -69,30 +71,14 @@ func FromPredicate[A any](pred func(A) bool, onFalse func(A) error) func(A) Read
|
|||||||
return RE.FromPredicate[ReaderEither[A]](pred, onFalse)
|
return RE.FromPredicate[ReaderEither[A]](pred, onFalse)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Fold[A, B any](onLeft func(error) R.Reader[B], onRight func(A) R.Reader[B]) func(ReaderEither[A]) R.Reader[B] {
|
|
||||||
return RE.Fold[ReaderEither[A]](onLeft, onRight)
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetOrElse[A any](onLeft func(error) R.Reader[A]) func(ReaderEither[A]) R.Reader[A] {
|
|
||||||
return RE.GetOrElse[ReaderEither[A]](onLeft)
|
|
||||||
}
|
|
||||||
|
|
||||||
func OrElse[A any](onLeft func(error) ReaderEither[A]) func(ReaderEither[A]) ReaderEither[A] {
|
func OrElse[A any](onLeft func(error) ReaderEither[A]) func(ReaderEither[A]) ReaderEither[A] {
|
||||||
return RE.OrElse[ReaderEither[A]](onLeft)
|
return RE.OrElse[ReaderEither[A]](onLeft)
|
||||||
}
|
}
|
||||||
|
|
||||||
func OrLeft[A any](onLeft func(error) R.Reader[error]) func(ReaderEither[A]) ReaderEither[A] {
|
|
||||||
return RE.OrLeft[ReaderEither[A], ReaderEither[A]](onLeft)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Ask() ReaderEither[context.Context] {
|
func Ask() ReaderEither[context.Context] {
|
||||||
return RE.Ask[ReaderEither[context.Context]]()
|
return RE.Ask[ReaderEither[context.Context]]()
|
||||||
}
|
}
|
||||||
|
|
||||||
func Asks[A any](r R.Reader[A]) ReaderEither[A] {
|
|
||||||
return RE.Asks[R.Reader[A], ReaderEither[A]](r)
|
|
||||||
}
|
|
||||||
|
|
||||||
func MonadChainEitherK[A, B any](ma ReaderEither[A], f func(A) ET.Either[error, B]) ReaderEither[B] {
|
func MonadChainEitherK[A, B any](ma ReaderEither[A], f func(A) ET.Either[error, B]) ReaderEither[B] {
|
||||||
return RE.MonadChainEitherK[ReaderEither[A], ReaderEither[B]](ma, f)
|
return RE.MonadChainEitherK[ReaderEither[A], ReaderEither[B]](ma, f)
|
||||||
}
|
}
|
||||||
@@ -104,3 +90,11 @@ func ChainEitherK[A, B any](f func(A) ET.Either[error, B]) func(ma ReaderEither[
|
|||||||
func ChainOptionK[A, B any](onNone func() error) func(func(A) O.Option[B]) func(ReaderEither[A]) ReaderEither[B] {
|
func ChainOptionK[A, B any](onNone func() error) func(func(A) O.Option[B]) func(ReaderEither[A]) ReaderEither[B] {
|
||||||
return RE.ChainOptionK[ReaderEither[A], ReaderEither[B]](onNone)
|
return RE.ChainOptionK[ReaderEither[A], ReaderEither[B]](onNone)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MonadFlap[B, A any](fab ReaderEither[func(A) B], a A) ReaderEither[B] {
|
||||||
|
return RE.MonadFlap[ReaderEither[func(A) B], ReaderEither[B]](fab, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Flap[B, A any](a A) func(ReaderEither[func(A) B]) ReaderEither[B] {
|
||||||
|
return RE.Flap[ReaderEither[func(A) B], ReaderEither[B]](a)
|
||||||
|
}
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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
|
package readereither
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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 implements a specialization of the Reader monad assuming a golang context as the context of the monad and a standard golang error
|
// Package readereither implements a specialization of the Reader monad assuming a golang context as the context of the monad and a standard golang error
|
||||||
package readereither
|
package readereither
|
||||||
|
|
||||||
|
@@ -1,16 +0,0 @@
|
|||||||
package readerio
|
|
||||||
|
|
||||||
import (
|
|
||||||
IO "github.com/IBM/fp-go/io"
|
|
||||||
R "github.com/IBM/fp-go/readerio/generic"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TraverseArray transforms an array
|
|
||||||
func TraverseArray[A, B any](f func(A) ReaderIO[B]) func([]A) ReaderIO[[]B] {
|
|
||||||
return R.TraverseArray[ReaderIO[B], ReaderIO[[]B], IO.IO[B], IO.IO[[]B], []A](f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SequenceArray converts a homogeneous sequence of either into an either of sequence
|
|
||||||
func SequenceArray[A any](ma []ReaderIO[A]) ReaderIO[[]A] {
|
|
||||||
return R.SequenceArray[ReaderIO[A], ReaderIO[[]A]](ma)
|
|
||||||
}
|
|
@@ -1,27 +0,0 @@
|
|||||||
package readerio
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
IO "github.com/IBM/fp-go/io"
|
|
||||||
R "github.com/IBM/fp-go/readerio/generic"
|
|
||||||
)
|
|
||||||
|
|
||||||
// these functions curry a golang function with the context as the firsr parameter into a either reader with the context as the last parameter
|
|
||||||
// this goes back to the advice in https://pkg.go.dev/context to put the context as a first parameter as a convention
|
|
||||||
|
|
||||||
func From0[A any](f func(context.Context) IO.IO[A]) func() ReaderIO[A] {
|
|
||||||
return R.From0[ReaderIO[A]](f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func From1[T1, A any](f func(context.Context, T1) IO.IO[A]) func(T1) ReaderIO[A] {
|
|
||||||
return R.From1[ReaderIO[A]](f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func From2[T1, T2, A any](f func(context.Context, T1, T2) IO.IO[A]) func(T1, T2) ReaderIO[A] {
|
|
||||||
return R.From2[ReaderIO[A]](f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func From3[T1, T2, T3, A any](f func(context.Context, T1, T2, T3) IO.IO[A]) func(T1, T2, T3) ReaderIO[A] {
|
|
||||||
return R.From3[ReaderIO[A]](f)
|
|
||||||
}
|
|
@@ -1,44 +0,0 @@
|
|||||||
package readerio
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
R "github.com/IBM/fp-go/readerio/generic"
|
|
||||||
)
|
|
||||||
|
|
||||||
func MonadMap[A, B any](fa ReaderIO[A], f func(A) B) ReaderIO[B] {
|
|
||||||
return R.MonadMap[ReaderIO[A], ReaderIO[B]](fa, f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Map[A, B any](f func(A) B) func(ReaderIO[A]) ReaderIO[B] {
|
|
||||||
return R.Map[ReaderIO[A], ReaderIO[B]](f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func MonadChain[A, B any](ma ReaderIO[A], f func(A) ReaderIO[B]) ReaderIO[B] {
|
|
||||||
return R.MonadChain(ma, f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Chain[A, B any](f func(A) ReaderIO[B]) func(ReaderIO[A]) ReaderIO[B] {
|
|
||||||
return R.Chain[ReaderIO[A]](f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Of[A any](a A) ReaderIO[A] {
|
|
||||||
return R.Of[ReaderIO[A]](a)
|
|
||||||
}
|
|
||||||
|
|
||||||
func MonadAp[A, B any](fab ReaderIO[func(A) B], fa ReaderIO[A]) ReaderIO[B] {
|
|
||||||
return R.MonadAp[ReaderIO[A], ReaderIO[B]](fab, fa)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Ap[A, B any](fa ReaderIO[A]) func(ReaderIO[func(A) B]) ReaderIO[B] {
|
|
||||||
return R.Ap[ReaderIO[A], ReaderIO[B], ReaderIO[func(A) B]](fa)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Ask() ReaderIO[context.Context] {
|
|
||||||
return R.Ask[ReaderIO[context.Context]]()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Defer creates an IO by creating a brand new IO via a generator function, each time
|
|
||||||
func Defer[A any](gen func() ReaderIO[A]) ReaderIO[A] {
|
|
||||||
return R.Defer[ReaderIO[A]](gen)
|
|
||||||
}
|
|
@@ -1,65 +0,0 @@
|
|||||||
package readerio
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
F "github.com/IBM/fp-go/function"
|
|
||||||
IO "github.com/IBM/fp-go/io"
|
|
||||||
T "github.com/IBM/fp-go/tuple"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GoFunction(ctx context.Context, data string) IO.IO[string] {
|
|
||||||
return func() string {
|
|
||||||
return strings.ToUpper(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func GoIntFunction(ctx context.Context, data string, number int) IO.IO[string] {
|
|
||||||
return func() string {
|
|
||||||
return fmt.Sprintf("%s: %d", data, number)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReaderFrom(t *testing.T) {
|
|
||||||
ctx := context.Background()
|
|
||||||
f := From1(GoFunction)
|
|
||||||
|
|
||||||
result := f("input")(ctx)
|
|
||||||
|
|
||||||
assert.Equal(t, result(), "INPUT")
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func MyFinalResult(left, right string) string {
|
|
||||||
return fmt.Sprintf("%s-%s", left, right)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReadersFrom(t *testing.T) {
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
f1 := From1(GoFunction)
|
|
||||||
f2 := From2(GoIntFunction)
|
|
||||||
|
|
||||||
result1 := f1("input")(ctx)
|
|
||||||
result2 := f2("input", 10)(ctx)
|
|
||||||
|
|
||||||
result3 := MyFinalResult(result1(), result2())
|
|
||||||
|
|
||||||
h := F.Pipe1(
|
|
||||||
SequenceT2(f1("input"), f2("input", 10)),
|
|
||||||
Map(T.Tupled2(MyFinalResult)),
|
|
||||||
)
|
|
||||||
|
|
||||||
composedResult := h(ctx)
|
|
||||||
|
|
||||||
assert.Equal(t, result1(), "INPUT")
|
|
||||||
assert.Equal(t, result2(), "input: 10")
|
|
||||||
assert.Equal(t, result3, "INPUT-input: 10")
|
|
||||||
|
|
||||||
assert.Equal(t, composedResult(), "INPUT-input: 10")
|
|
||||||
|
|
||||||
}
|
|
@@ -1,42 +0,0 @@
|
|||||||
package readerio
|
|
||||||
|
|
||||||
import (
|
|
||||||
R "github.com/IBM/fp-go/readerio/generic"
|
|
||||||
T "github.com/IBM/fp-go/tuple"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SequenceT converts n inputs of higher kinded types into a higher kinded types of n strongly typed values, represented as a tuple
|
|
||||||
|
|
||||||
func SequenceT1[A any](a ReaderIO[A]) ReaderIO[T.Tuple1[A]] {
|
|
||||||
return R.SequenceT1[
|
|
||||||
ReaderIO[A],
|
|
||||||
ReaderIO[T.Tuple1[A]],
|
|
||||||
](a)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SequenceT2[A, B any](a ReaderIO[A], b ReaderIO[B]) ReaderIO[T.Tuple2[A, B]] {
|
|
||||||
return R.SequenceT2[
|
|
||||||
ReaderIO[A],
|
|
||||||
ReaderIO[B],
|
|
||||||
ReaderIO[T.Tuple2[A, B]],
|
|
||||||
](a, b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SequenceT3[A, B, C any](a ReaderIO[A], b ReaderIO[B], c ReaderIO[C]) ReaderIO[T.Tuple3[A, B, C]] {
|
|
||||||
return R.SequenceT3[
|
|
||||||
ReaderIO[A],
|
|
||||||
ReaderIO[B],
|
|
||||||
ReaderIO[C],
|
|
||||||
ReaderIO[T.Tuple3[A, B, C]],
|
|
||||||
](a, b, c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SequenceT4[A, B, C, D any](a ReaderIO[A], b ReaderIO[B], c ReaderIO[C], d ReaderIO[D]) ReaderIO[T.Tuple4[A, B, C, D]] {
|
|
||||||
return R.SequenceT4[
|
|
||||||
ReaderIO[A],
|
|
||||||
ReaderIO[B],
|
|
||||||
ReaderIO[C],
|
|
||||||
ReaderIO[D],
|
|
||||||
ReaderIO[T.Tuple4[A, B, C, D]],
|
|
||||||
](a, b, c, d)
|
|
||||||
}
|
|
@@ -1,11 +0,0 @@
|
|||||||
// Package readerio implements a specialization of the ReaderIO monad assuming a golang context as the context of the monad
|
|
||||||
package readerio
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
R "github.com/IBM/fp-go/readerio"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ReaderIO is a specialization of the ReaderIO monad assuming a golang context as the context of the monad
|
|
||||||
type ReaderIO[A any] R.ReaderIO[context.Context, A]
|
|
37
context/readerioeither/bracket.go
Normal file
37
context/readerioeither/bracket.go
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
// Copyright (c) 2023 IBM Corp.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package readerioeither
|
||||||
|
|
||||||
|
import (
|
||||||
|
G "github.com/IBM/fp-go/context/readerioeither/generic"
|
||||||
|
E "github.com/IBM/fp-go/either"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Bracket makes sure that a resource is cleaned up in the event of an error. The release action is called regardless of
|
||||||
|
// whether the body action returns and error or not.
|
||||||
|
func Bracket[
|
||||||
|
A, B, ANY any](
|
||||||
|
|
||||||
|
acquire ReaderIOEither[A],
|
||||||
|
use func(A) ReaderIOEither[B],
|
||||||
|
release func(A, E.Either[error, B]) ReaderIOEither[ANY],
|
||||||
|
) ReaderIOEither[B] {
|
||||||
|
return G.Bracket[ReaderIOEither[A], ReaderIOEither[B], ReaderIOEither[ANY]](
|
||||||
|
acquire,
|
||||||
|
use,
|
||||||
|
release,
|
||||||
|
)
|
||||||
|
}
|
@@ -1,10 +1,25 @@
|
|||||||
|
// 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
|
package readerioeither
|
||||||
|
|
||||||
import (
|
import (
|
||||||
G "github.com/IBM/fp-go/context/readerioeither/generic"
|
G "github.com/IBM/fp-go/context/readerioeither/generic"
|
||||||
)
|
)
|
||||||
|
|
||||||
// WithContext wraps an existing ReaderIOEither and performs a context check for cancellation before delegating
|
// WithContext wraps an existing [ReaderIOEither] and performs a context check for cancellation before delegating
|
||||||
func WithContext[A any](ma ReaderIOEither[A]) ReaderIOEither[A] {
|
func WithContext[A any](ma ReaderIOEither[A]) ReaderIOEither[A] {
|
||||||
return G.WithContext(ma)
|
return G.WithContext(ma)
|
||||||
}
|
}
|
||||||
|
1
context/readerioeither/data/file.txt
Normal file
1
context/readerioeither/data/file.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Carsten
|
@@ -1,4 +1,19 @@
|
|||||||
// Package readerioeither contains a version of [ReaderIOEither] that takes a golang [context.Context] as its context
|
// 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 contains a version of [ReaderIOEither] that takes a golang [context.Context] as its context and that assumes the standard go error
|
||||||
package readerioeither
|
package readerioeither
|
||||||
|
|
||||||
//go:generate go run ../.. contextreaderioeither --count 10 --filename gen.go
|
//go:generate go run ../.. contextreaderioeither --count 10 --filename gen.go
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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
|
package readerioeither
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -8,7 +23,7 @@ import (
|
|||||||
EQ "github.com/IBM/fp-go/eq"
|
EQ "github.com/IBM/fp-go/eq"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Eq implements the equals predicate for values contained in the IOEither monad
|
// Eq implements the equals predicate for values contained in the [ReaderIOEither] monad
|
||||||
func Eq[A any](eq EQ.Eq[ET.Either[error, A]]) func(context.Context) EQ.Eq[ReaderIOEither[A]] {
|
func Eq[A any](eq EQ.Eq[ET.Either[error, A]]) func(context.Context) EQ.Eq[ReaderIOEither[A]] {
|
||||||
return G.Eq[ReaderIOEither[A]](eq)
|
return G.Eq[ReaderIOEither[A]](eq)
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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 exec
|
package exec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
3
context/readerioeither/file/data/file.json
Normal file
3
context/readerioeither/file/data/file.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"data": "Carsten"
|
||||||
|
}
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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 file
|
package file
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -10,30 +25,36 @@ import (
|
|||||||
F "github.com/IBM/fp-go/function"
|
F "github.com/IBM/fp-go/function"
|
||||||
"github.com/IBM/fp-go/internal/file"
|
"github.com/IBM/fp-go/internal/file"
|
||||||
IOE "github.com/IBM/fp-go/ioeither"
|
IOE "github.com/IBM/fp-go/ioeither"
|
||||||
|
IOEF "github.com/IBM/fp-go/ioeither/file"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
openIOE = IOE.Eitherize1(os.Open)
|
|
||||||
// Open opens a file for reading within the given context
|
// Open opens a file for reading within the given context
|
||||||
Open = F.Flow3(
|
Open = F.Flow3(
|
||||||
openIOE,
|
IOEF.Open,
|
||||||
RIOE.FromIOEither[*os.File],
|
RIOE.FromIOEither[*os.File],
|
||||||
RIOE.WithContext[*os.File],
|
RIOE.WithContext[*os.File],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Remove removes a file by name
|
||||||
|
Remove = F.Flow2(
|
||||||
|
IOEF.Remove,
|
||||||
|
RIOE.FromIOEither[string],
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Close closes an object
|
// Close closes an object
|
||||||
func Close[C io.Closer](c C) RIOE.ReaderIOEither[any] {
|
func Close[C io.Closer](c C) RIOE.ReaderIOEither[any] {
|
||||||
return RIOE.FromIOEither(func() ET.Either[error, any] {
|
return F.Pipe2(
|
||||||
return ET.TryCatchError(func() (any, error) {
|
c,
|
||||||
return c, c.Close()
|
IOEF.Close[C],
|
||||||
})
|
RIOE.FromIOEither[any],
|
||||||
})
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadFile reads a file in the scope of a context
|
// ReadFile reads a file in the scope of a context
|
||||||
func ReadFile(path string) RIOE.ReaderIOEither[[]byte] {
|
func ReadFile(path string) RIOE.ReaderIOEither[[]byte] {
|
||||||
return RIOE.WithResource[*os.File, []byte](Open(path), Close[*os.File])(func(r *os.File) RIOE.ReaderIOEither[[]byte] {
|
return RIOE.WithResource[[]byte](Open(path), Close[*os.File])(func(r *os.File) RIOE.ReaderIOEither[[]byte] {
|
||||||
return func(ctx context.Context) IOE.IOEither[error, []byte] {
|
return func(ctx context.Context) IOE.IOEither[error, []byte] {
|
||||||
return IOE.MakeIO(func() ET.Either[error, []byte] {
|
return IOE.MakeIO(func() ET.Either[error, []byte] {
|
||||||
return file.ReadAll(ctx, r)
|
return file.ReadAll(ctx, r)
|
||||||
|
51
context/readerioeither/file/file_test.go
Normal file
51
context/readerioeither/file/file_test.go
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
// 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 file
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
R "github.com/IBM/fp-go/context/readerioeither"
|
||||||
|
F "github.com/IBM/fp-go/function"
|
||||||
|
IO "github.com/IBM/fp-go/io"
|
||||||
|
J "github.com/IBM/fp-go/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RecordType struct {
|
||||||
|
Data string `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func getData(r RecordType) string {
|
||||||
|
return r.Data
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleReadFile() {
|
||||||
|
|
||||||
|
data := F.Pipe3(
|
||||||
|
ReadFile("./data/file.json"),
|
||||||
|
R.ChainEitherK(J.Unmarshal[RecordType]),
|
||||||
|
R.ChainFirstIOK(IO.Logf[RecordType]("Log: %v")),
|
||||||
|
R.Map(getData),
|
||||||
|
)
|
||||||
|
|
||||||
|
result := data(context.Background())
|
||||||
|
|
||||||
|
fmt.Println(result())
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Right[<nil>, string](Carsten)
|
||||||
|
}
|
52
context/readerioeither/file/tempfile.go
Normal file
52
context/readerioeither/file/tempfile.go
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
// 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 file
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
RIOE "github.com/IBM/fp-go/context/readerioeither"
|
||||||
|
F "github.com/IBM/fp-go/function"
|
||||||
|
IO "github.com/IBM/fp-go/io"
|
||||||
|
IOF "github.com/IBM/fp-go/io/file"
|
||||||
|
IOEF "github.com/IBM/fp-go/ioeither/file"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// onCreateTempFile creates a temp file with sensible defaults
|
||||||
|
onCreateTempFile = CreateTemp("", "*")
|
||||||
|
// destroy handler
|
||||||
|
onReleaseTempFile = F.Flow4(
|
||||||
|
IOF.Close[*os.File],
|
||||||
|
IO.Map((*os.File).Name),
|
||||||
|
RIOE.FromIO[string],
|
||||||
|
RIOE.Chain(Remove),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateTemp created a temp file with proper parametrization
|
||||||
|
func CreateTemp(dir, pattern string) RIOE.ReaderIOEither[*os.File] {
|
||||||
|
return F.Pipe2(
|
||||||
|
IOEF.CreateTemp(dir, pattern),
|
||||||
|
RIOE.FromIOEither[*os.File],
|
||||||
|
RIOE.WithContext[*os.File],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithTempFile creates a temporary file, then invokes a callback to create a resource based on the file, then close and remove the temp file
|
||||||
|
func WithTempFile[A any](f func(*os.File) RIOE.ReaderIOEither[A]) RIOE.ReaderIOEither[A] {
|
||||||
|
return RIOE.WithResource[A](onCreateTempFile, onReleaseTempFile)(f)
|
||||||
|
}
|
47
context/readerioeither/file/tempfile_test.go
Normal file
47
context/readerioeither/file/tempfile_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 file
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
RIOE "github.com/IBM/fp-go/context/readerioeither"
|
||||||
|
E "github.com/IBM/fp-go/either"
|
||||||
|
F "github.com/IBM/fp-go/function"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestWithTempFile(t *testing.T) {
|
||||||
|
|
||||||
|
res := WithTempFile(onWriteAll[*os.File]([]byte("Carsten")))
|
||||||
|
|
||||||
|
assert.Equal(t, E.Of[error]([]byte("Carsten")), res(context.Background())())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithTempFileOnClosedFile(t *testing.T) {
|
||||||
|
|
||||||
|
res := WithTempFile(func(f *os.File) RIOE.ReaderIOEither[[]byte] {
|
||||||
|
return F.Pipe2(
|
||||||
|
f,
|
||||||
|
onWriteAll[*os.File]([]byte("Carsten")),
|
||||||
|
RIOE.ChainFirst(F.Constant1[[]byte](Close(f))),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(t, E.Of[error]([]byte("Carsten")), res(context.Background())())
|
||||||
|
}
|
57
context/readerioeither/file/write.go
Normal file
57
context/readerioeither/file/write.go
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
// 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 file
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
RIOE "github.com/IBM/fp-go/context/readerioeither"
|
||||||
|
F "github.com/IBM/fp-go/function"
|
||||||
|
)
|
||||||
|
|
||||||
|
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) {
|
||||||
|
return func() ([]byte, error) {
|
||||||
|
_, err := w.Write(data)
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
RIOE.WithContext[[]byte],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteAll uses a generator function to create a stream, writes data to it and closes it
|
||||||
|
func WriteAll[W io.WriteCloser](data []byte) func(acquire RIOE.ReaderIOEither[W]) RIOE.ReaderIOEither[[]byte] {
|
||||||
|
onWrite := onWriteAll[W](data)
|
||||||
|
return func(onCreate RIOE.ReaderIOEither[W]) RIOE.ReaderIOEither[[]byte] {
|
||||||
|
return RIOE.WithResource[[]byte](
|
||||||
|
onCreate,
|
||||||
|
Close[W])(
|
||||||
|
onWrite,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write uses a generator function to create a stream, writes data to it and closes it
|
||||||
|
func Write[R any, W io.WriteCloser](acquire RIOE.ReaderIOEither[W]) func(use func(W) RIOE.ReaderIOEither[R]) RIOE.ReaderIOEither[R] {
|
||||||
|
return RIOE.WithResource[R](
|
||||||
|
acquire,
|
||||||
|
Close[W])
|
||||||
|
}
|
@@ -2,12 +2,13 @@ package readerioeither
|
|||||||
|
|
||||||
// Code generated by go generate; DO NOT EDIT.
|
// Code generated by go generate; DO NOT EDIT.
|
||||||
// This file was generated by robots at
|
// This file was generated by robots at
|
||||||
// 2023-07-19 16:18:34.1521763 +0200 CEST m=+0.011558001
|
// 2023-10-23 08:30:39.012572 +0200 CEST m=+0.008846101
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
G "github.com/IBM/fp-go/context/readerioeither/generic"
|
G "github.com/IBM/fp-go/context/readerioeither/generic"
|
||||||
|
T "github.com/IBM/fp-go/tuple"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Eitherize0 converts a function with 0 parameters returning a tuple into a function with 0 parameters returning a [ReaderIOEither[R]]
|
// Eitherize0 converts a function with 0 parameters returning a tuple into a function with 0 parameters returning a [ReaderIOEither[R]]
|
||||||
@@ -22,56 +23,506 @@ func Eitherize1[F ~func(context.Context, T0) (R, error), T0, R any](f F) func(T0
|
|||||||
return G.Eitherize1[ReaderIOEither[R]](f)
|
return G.Eitherize1[ReaderIOEither[R]](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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceSeqT1 converts 1 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple1].
|
||||||
|
func SequenceSeqT1[T1 any](t1 ReaderIOEither[T1]) ReaderIOEither[T.Tuple1[T1]] {
|
||||||
|
return G.SequenceSeqT1[ReaderIOEither[T.Tuple1[T1]]](t1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceParT1 converts 1 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple1].
|
||||||
|
func SequenceParT1[T1 any](t1 ReaderIOEither[T1]) ReaderIOEither[T.Tuple1[T1]] {
|
||||||
|
return G.SequenceParT1[ReaderIOEither[T.Tuple1[T1]]](t1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceTuple1 converts a [T.Tuple1] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple1].
|
||||||
|
func SequenceTuple1[T1 any](t T.Tuple1[ReaderIOEither[T1]]) ReaderIOEither[T.Tuple1[T1]] {
|
||||||
|
return G.SequenceTuple1[ReaderIOEither[T.Tuple1[T1]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceSeqTuple1 converts a [T.Tuple1] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple1].
|
||||||
|
func SequenceSeqTuple1[T1 any](t T.Tuple1[ReaderIOEither[T1]]) ReaderIOEither[T.Tuple1[T1]] {
|
||||||
|
return G.SequenceSeqTuple1[ReaderIOEither[T.Tuple1[T1]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceParTuple1 converts a [T.Tuple1] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple1].
|
||||||
|
func SequenceParTuple1[T1 any](t T.Tuple1[ReaderIOEither[T1]]) ReaderIOEither[T.Tuple1[T1]] {
|
||||||
|
return G.SequenceParTuple1[ReaderIOEither[T.Tuple1[T1]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseTuple1 converts a [T.Tuple1] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple1].
|
||||||
|
func TraverseTuple1[F1 ~func(A1) ReaderIOEither[T1], A1, T1 any](f1 F1) func(T.Tuple1[A1]) ReaderIOEither[T.Tuple1[T1]] {
|
||||||
|
return G.TraverseTuple1[ReaderIOEither[T.Tuple1[T1]]](f1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseSeqTuple1 converts a [T.Tuple1] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple1].
|
||||||
|
func TraverseSeqTuple1[F1 ~func(A1) ReaderIOEither[T1], A1, T1 any](f1 F1) func(T.Tuple1[A1]) ReaderIOEither[T.Tuple1[T1]] {
|
||||||
|
return G.TraverseSeqTuple1[ReaderIOEither[T.Tuple1[T1]]](f1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseParTuple1 converts a [T.Tuple1] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple1].
|
||||||
|
func TraverseParTuple1[F1 ~func(A1) ReaderIOEither[T1], A1, T1 any](f1 F1) func(T.Tuple1[A1]) ReaderIOEither[T.Tuple1[T1]] {
|
||||||
|
return G.TraverseParTuple1[ReaderIOEither[T.Tuple1[T1]]](f1)
|
||||||
|
}
|
||||||
|
|
||||||
// Eitherize2 converts a function with 2 parameters returning a tuple into a function with 2 parameters returning a [ReaderIOEither[R]]
|
// Eitherize2 converts a function with 2 parameters returning a tuple into a function with 2 parameters returning a [ReaderIOEither[R]]
|
||||||
// The inverse function is [Uneitherize2]
|
// The inverse function is [Uneitherize2]
|
||||||
func Eitherize2[F ~func(context.Context, T0, T1) (R, error), T0, T1, R any](f F) func(T0, T1) ReaderIOEither[R] {
|
func Eitherize2[F ~func(context.Context, T0, T1) (R, error), T0, T1, R any](f F) func(T0, T1) ReaderIOEither[R] {
|
||||||
return G.Eitherize2[ReaderIOEither[R]](f)
|
return G.Eitherize2[ReaderIOEither[R]](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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceSeqT2 converts 2 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple2].
|
||||||
|
func SequenceSeqT2[T1, T2 any](t1 ReaderIOEither[T1], t2 ReaderIOEither[T2]) ReaderIOEither[T.Tuple2[T1, T2]] {
|
||||||
|
return G.SequenceSeqT2[ReaderIOEither[T.Tuple2[T1, T2]]](t1, t2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceParT2 converts 2 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple2].
|
||||||
|
func SequenceParT2[T1, T2 any](t1 ReaderIOEither[T1], t2 ReaderIOEither[T2]) ReaderIOEither[T.Tuple2[T1, T2]] {
|
||||||
|
return G.SequenceParT2[ReaderIOEither[T.Tuple2[T1, T2]]](t1, t2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceTuple2 converts a [T.Tuple2] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple2].
|
||||||
|
func SequenceTuple2[T1, T2 any](t T.Tuple2[ReaderIOEither[T1], ReaderIOEither[T2]]) ReaderIOEither[T.Tuple2[T1, T2]] {
|
||||||
|
return G.SequenceTuple2[ReaderIOEither[T.Tuple2[T1, T2]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceSeqTuple2 converts a [T.Tuple2] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple2].
|
||||||
|
func SequenceSeqTuple2[T1, T2 any](t T.Tuple2[ReaderIOEither[T1], ReaderIOEither[T2]]) ReaderIOEither[T.Tuple2[T1, T2]] {
|
||||||
|
return G.SequenceSeqTuple2[ReaderIOEither[T.Tuple2[T1, T2]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceParTuple2 converts a [T.Tuple2] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple2].
|
||||||
|
func SequenceParTuple2[T1, T2 any](t T.Tuple2[ReaderIOEither[T1], ReaderIOEither[T2]]) ReaderIOEither[T.Tuple2[T1, T2]] {
|
||||||
|
return G.SequenceParTuple2[ReaderIOEither[T.Tuple2[T1, T2]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseTuple2 converts a [T.Tuple2] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple2].
|
||||||
|
func TraverseTuple2[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], A1, T1, A2, T2 any](f1 F1, f2 F2) func(T.Tuple2[A1, A2]) ReaderIOEither[T.Tuple2[T1, T2]] {
|
||||||
|
return G.TraverseTuple2[ReaderIOEither[T.Tuple2[T1, T2]]](f1, f2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseSeqTuple2 converts a [T.Tuple2] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple2].
|
||||||
|
func TraverseSeqTuple2[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], A1, T1, A2, T2 any](f1 F1, f2 F2) func(T.Tuple2[A1, A2]) ReaderIOEither[T.Tuple2[T1, T2]] {
|
||||||
|
return G.TraverseSeqTuple2[ReaderIOEither[T.Tuple2[T1, T2]]](f1, f2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseParTuple2 converts a [T.Tuple2] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple2].
|
||||||
|
func TraverseParTuple2[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], A1, T1, A2, T2 any](f1 F1, f2 F2) func(T.Tuple2[A1, A2]) ReaderIOEither[T.Tuple2[T1, T2]] {
|
||||||
|
return G.TraverseParTuple2[ReaderIOEither[T.Tuple2[T1, T2]]](f1, f2)
|
||||||
|
}
|
||||||
|
|
||||||
// Eitherize3 converts a function with 3 parameters returning a tuple into a function with 3 parameters returning a [ReaderIOEither[R]]
|
// Eitherize3 converts a function with 3 parameters returning a tuple into a function with 3 parameters returning a [ReaderIOEither[R]]
|
||||||
// The inverse function is [Uneitherize3]
|
// The inverse function is [Uneitherize3]
|
||||||
func Eitherize3[F ~func(context.Context, T0, T1, T2) (R, error), T0, T1, T2, R any](f F) func(T0, T1, T2) ReaderIOEither[R] {
|
func Eitherize3[F ~func(context.Context, T0, T1, T2) (R, error), T0, T1, T2, R any](f F) func(T0, T1, T2) ReaderIOEither[R] {
|
||||||
return G.Eitherize3[ReaderIOEither[R]](f)
|
return G.Eitherize3[ReaderIOEither[R]](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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceSeqT3 converts 3 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple3].
|
||||||
|
func SequenceSeqT3[T1, T2, T3 any](t1 ReaderIOEither[T1], t2 ReaderIOEither[T2], t3 ReaderIOEither[T3]) ReaderIOEither[T.Tuple3[T1, T2, T3]] {
|
||||||
|
return G.SequenceSeqT3[ReaderIOEither[T.Tuple3[T1, T2, T3]]](t1, t2, t3)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceParT3 converts 3 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple3].
|
||||||
|
func SequenceParT3[T1, T2, T3 any](t1 ReaderIOEither[T1], t2 ReaderIOEither[T2], t3 ReaderIOEither[T3]) ReaderIOEither[T.Tuple3[T1, T2, T3]] {
|
||||||
|
return G.SequenceParT3[ReaderIOEither[T.Tuple3[T1, T2, T3]]](t1, t2, t3)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceTuple3 converts a [T.Tuple3] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple3].
|
||||||
|
func SequenceTuple3[T1, T2, T3 any](t T.Tuple3[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3]]) ReaderIOEither[T.Tuple3[T1, T2, T3]] {
|
||||||
|
return G.SequenceTuple3[ReaderIOEither[T.Tuple3[T1, T2, T3]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceSeqTuple3 converts a [T.Tuple3] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple3].
|
||||||
|
func SequenceSeqTuple3[T1, T2, T3 any](t T.Tuple3[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3]]) ReaderIOEither[T.Tuple3[T1, T2, T3]] {
|
||||||
|
return G.SequenceSeqTuple3[ReaderIOEither[T.Tuple3[T1, T2, T3]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceParTuple3 converts a [T.Tuple3] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple3].
|
||||||
|
func SequenceParTuple3[T1, T2, T3 any](t T.Tuple3[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3]]) ReaderIOEither[T.Tuple3[T1, T2, T3]] {
|
||||||
|
return G.SequenceParTuple3[ReaderIOEither[T.Tuple3[T1, T2, T3]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseTuple3 converts a [T.Tuple3] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple3].
|
||||||
|
func TraverseTuple3[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], A1, T1, A2, T2, A3, T3 any](f1 F1, f2 F2, f3 F3) func(T.Tuple3[A1, A2, A3]) ReaderIOEither[T.Tuple3[T1, T2, T3]] {
|
||||||
|
return G.TraverseTuple3[ReaderIOEither[T.Tuple3[T1, T2, T3]]](f1, f2, f3)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseSeqTuple3 converts a [T.Tuple3] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple3].
|
||||||
|
func TraverseSeqTuple3[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], A1, T1, A2, T2, A3, T3 any](f1 F1, f2 F2, f3 F3) func(T.Tuple3[A1, A2, A3]) ReaderIOEither[T.Tuple3[T1, T2, T3]] {
|
||||||
|
return G.TraverseSeqTuple3[ReaderIOEither[T.Tuple3[T1, T2, T3]]](f1, f2, f3)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseParTuple3 converts a [T.Tuple3] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple3].
|
||||||
|
func TraverseParTuple3[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], A1, T1, A2, T2, A3, T3 any](f1 F1, f2 F2, f3 F3) func(T.Tuple3[A1, A2, A3]) ReaderIOEither[T.Tuple3[T1, T2, T3]] {
|
||||||
|
return G.TraverseParTuple3[ReaderIOEither[T.Tuple3[T1, T2, T3]]](f1, f2, f3)
|
||||||
|
}
|
||||||
|
|
||||||
// Eitherize4 converts a function with 4 parameters returning a tuple into a function with 4 parameters returning a [ReaderIOEither[R]]
|
// Eitherize4 converts a function with 4 parameters returning a tuple into a function with 4 parameters returning a [ReaderIOEither[R]]
|
||||||
// The inverse function is [Uneitherize4]
|
// The inverse function is [Uneitherize4]
|
||||||
func Eitherize4[F ~func(context.Context, T0, T1, T2, T3) (R, error), T0, T1, T2, T3, R any](f F) func(T0, T1, T2, T3) ReaderIOEither[R] {
|
func Eitherize4[F ~func(context.Context, T0, T1, T2, T3) (R, error), T0, T1, T2, T3, R any](f F) func(T0, T1, T2, T3) ReaderIOEither[R] {
|
||||||
return G.Eitherize4[ReaderIOEither[R]](f)
|
return G.Eitherize4[ReaderIOEither[R]](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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceSeqT4 converts 4 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple4].
|
||||||
|
func SequenceSeqT4[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.SequenceSeqT4[ReaderIOEither[T.Tuple4[T1, T2, T3, T4]]](t1, t2, t3, t4)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceParT4 converts 4 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple4].
|
||||||
|
func SequenceParT4[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.SequenceParT4[ReaderIOEither[T.Tuple4[T1, T2, T3, T4]]](t1, t2, t3, t4)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceTuple4 converts a [T.Tuple4] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple4].
|
||||||
|
func SequenceTuple4[T1, T2, T3, T4 any](t T.Tuple4[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3], ReaderIOEither[T4]]) ReaderIOEither[T.Tuple4[T1, T2, T3, T4]] {
|
||||||
|
return G.SequenceTuple4[ReaderIOEither[T.Tuple4[T1, T2, T3, T4]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceSeqTuple4 converts a [T.Tuple4] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple4].
|
||||||
|
func SequenceSeqTuple4[T1, T2, T3, T4 any](t T.Tuple4[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3], ReaderIOEither[T4]]) ReaderIOEither[T.Tuple4[T1, T2, T3, T4]] {
|
||||||
|
return G.SequenceSeqTuple4[ReaderIOEither[T.Tuple4[T1, T2, T3, T4]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceParTuple4 converts a [T.Tuple4] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple4].
|
||||||
|
func SequenceParTuple4[T1, T2, T3, T4 any](t T.Tuple4[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3], ReaderIOEither[T4]]) ReaderIOEither[T.Tuple4[T1, T2, T3, T4]] {
|
||||||
|
return G.SequenceParTuple4[ReaderIOEither[T.Tuple4[T1, T2, T3, T4]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseTuple4 converts a [T.Tuple4] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple4].
|
||||||
|
func TraverseTuple4[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], F4 ~func(A4) ReaderIOEither[T4], A1, T1, A2, T2, A3, T3, A4, T4 any](f1 F1, f2 F2, f3 F3, f4 F4) func(T.Tuple4[A1, A2, A3, A4]) ReaderIOEither[T.Tuple4[T1, T2, T3, T4]] {
|
||||||
|
return G.TraverseTuple4[ReaderIOEither[T.Tuple4[T1, T2, T3, T4]]](f1, f2, f3, f4)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseSeqTuple4 converts a [T.Tuple4] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple4].
|
||||||
|
func TraverseSeqTuple4[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], F4 ~func(A4) ReaderIOEither[T4], A1, T1, A2, T2, A3, T3, A4, T4 any](f1 F1, f2 F2, f3 F3, f4 F4) func(T.Tuple4[A1, A2, A3, A4]) ReaderIOEither[T.Tuple4[T1, T2, T3, T4]] {
|
||||||
|
return G.TraverseSeqTuple4[ReaderIOEither[T.Tuple4[T1, T2, T3, T4]]](f1, f2, f3, f4)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseParTuple4 converts a [T.Tuple4] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple4].
|
||||||
|
func TraverseParTuple4[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], F4 ~func(A4) ReaderIOEither[T4], A1, T1, A2, T2, A3, T3, A4, T4 any](f1 F1, f2 F2, f3 F3, f4 F4) func(T.Tuple4[A1, A2, A3, A4]) ReaderIOEither[T.Tuple4[T1, T2, T3, T4]] {
|
||||||
|
return G.TraverseParTuple4[ReaderIOEither[T.Tuple4[T1, T2, T3, T4]]](f1, f2, f3, f4)
|
||||||
|
}
|
||||||
|
|
||||||
// Eitherize5 converts a function with 5 parameters returning a tuple into a function with 5 parameters returning a [ReaderIOEither[R]]
|
// Eitherize5 converts a function with 5 parameters returning a tuple into a function with 5 parameters returning a [ReaderIOEither[R]]
|
||||||
// The inverse function is [Uneitherize5]
|
// The inverse function is [Uneitherize5]
|
||||||
func Eitherize5[F ~func(context.Context, T0, T1, T2, T3, T4) (R, error), T0, T1, T2, T3, T4, R any](f F) func(T0, T1, T2, T3, T4) ReaderIOEither[R] {
|
func Eitherize5[F ~func(context.Context, T0, T1, T2, T3, T4) (R, error), T0, T1, T2, T3, T4, R any](f F) func(T0, T1, T2, T3, T4) ReaderIOEither[R] {
|
||||||
return G.Eitherize5[ReaderIOEither[R]](f)
|
return G.Eitherize5[ReaderIOEither[R]](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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceSeqT5 converts 5 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple5].
|
||||||
|
func SequenceSeqT5[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.SequenceSeqT5[ReaderIOEither[T.Tuple5[T1, T2, T3, T4, T5]]](t1, t2, t3, t4, t5)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceParT5 converts 5 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple5].
|
||||||
|
func SequenceParT5[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.SequenceParT5[ReaderIOEither[T.Tuple5[T1, T2, T3, T4, T5]]](t1, t2, t3, t4, t5)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceTuple5 converts a [T.Tuple5] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple5].
|
||||||
|
func SequenceTuple5[T1, T2, T3, T4, T5 any](t T.Tuple5[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3], ReaderIOEither[T4], ReaderIOEither[T5]]) ReaderIOEither[T.Tuple5[T1, T2, T3, T4, T5]] {
|
||||||
|
return G.SequenceTuple5[ReaderIOEither[T.Tuple5[T1, T2, T3, T4, T5]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceSeqTuple5 converts a [T.Tuple5] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple5].
|
||||||
|
func SequenceSeqTuple5[T1, T2, T3, T4, T5 any](t T.Tuple5[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3], ReaderIOEither[T4], ReaderIOEither[T5]]) ReaderIOEither[T.Tuple5[T1, T2, T3, T4, T5]] {
|
||||||
|
return G.SequenceSeqTuple5[ReaderIOEither[T.Tuple5[T1, T2, T3, T4, T5]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceParTuple5 converts a [T.Tuple5] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple5].
|
||||||
|
func SequenceParTuple5[T1, T2, T3, T4, T5 any](t T.Tuple5[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3], ReaderIOEither[T4], ReaderIOEither[T5]]) ReaderIOEither[T.Tuple5[T1, T2, T3, T4, T5]] {
|
||||||
|
return G.SequenceParTuple5[ReaderIOEither[T.Tuple5[T1, T2, T3, T4, T5]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseTuple5 converts a [T.Tuple5] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple5].
|
||||||
|
func TraverseTuple5[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], F4 ~func(A4) ReaderIOEither[T4], F5 ~func(A5) ReaderIOEither[T5], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) func(T.Tuple5[A1, A2, A3, A4, A5]) ReaderIOEither[T.Tuple5[T1, T2, T3, T4, T5]] {
|
||||||
|
return G.TraverseTuple5[ReaderIOEither[T.Tuple5[T1, T2, T3, T4, T5]]](f1, f2, f3, f4, f5)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseSeqTuple5 converts a [T.Tuple5] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple5].
|
||||||
|
func TraverseSeqTuple5[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], F4 ~func(A4) ReaderIOEither[T4], F5 ~func(A5) ReaderIOEither[T5], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) func(T.Tuple5[A1, A2, A3, A4, A5]) ReaderIOEither[T.Tuple5[T1, T2, T3, T4, T5]] {
|
||||||
|
return G.TraverseSeqTuple5[ReaderIOEither[T.Tuple5[T1, T2, T3, T4, T5]]](f1, f2, f3, f4, f5)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseParTuple5 converts a [T.Tuple5] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple5].
|
||||||
|
func TraverseParTuple5[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], F4 ~func(A4) ReaderIOEither[T4], F5 ~func(A5) ReaderIOEither[T5], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) func(T.Tuple5[A1, A2, A3, A4, A5]) ReaderIOEither[T.Tuple5[T1, T2, T3, T4, T5]] {
|
||||||
|
return G.TraverseParTuple5[ReaderIOEither[T.Tuple5[T1, T2, T3, T4, T5]]](f1, f2, f3, f4, f5)
|
||||||
|
}
|
||||||
|
|
||||||
// Eitherize6 converts a function with 6 parameters returning a tuple into a function with 6 parameters returning a [ReaderIOEither[R]]
|
// Eitherize6 converts a function with 6 parameters returning a tuple into a function with 6 parameters returning a [ReaderIOEither[R]]
|
||||||
// The inverse function is [Uneitherize6]
|
// The inverse function is [Uneitherize6]
|
||||||
func Eitherize6[F ~func(context.Context, T0, T1, T2, T3, T4, T5) (R, error), T0, T1, T2, T3, T4, T5, R any](f F) func(T0, T1, T2, T3, T4, T5) ReaderIOEither[R] {
|
func Eitherize6[F ~func(context.Context, T0, T1, T2, T3, T4, T5) (R, error), T0, T1, T2, T3, T4, T5, R any](f F) func(T0, T1, T2, T3, T4, T5) ReaderIOEither[R] {
|
||||||
return G.Eitherize6[ReaderIOEither[R]](f)
|
return G.Eitherize6[ReaderIOEither[R]](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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceSeqT6 converts 6 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple6].
|
||||||
|
func SequenceSeqT6[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.SequenceSeqT6[ReaderIOEither[T.Tuple6[T1, T2, T3, T4, T5, T6]]](t1, t2, t3, t4, t5, t6)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceParT6 converts 6 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple6].
|
||||||
|
func SequenceParT6[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.SequenceParT6[ReaderIOEither[T.Tuple6[T1, T2, T3, T4, T5, T6]]](t1, t2, t3, t4, t5, t6)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceTuple6 converts a [T.Tuple6] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple6].
|
||||||
|
func SequenceTuple6[T1, T2, T3, T4, T5, T6 any](t T.Tuple6[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3], ReaderIOEither[T4], ReaderIOEither[T5], ReaderIOEither[T6]]) ReaderIOEither[T.Tuple6[T1, T2, T3, T4, T5, T6]] {
|
||||||
|
return G.SequenceTuple6[ReaderIOEither[T.Tuple6[T1, T2, T3, T4, T5, T6]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceSeqTuple6 converts a [T.Tuple6] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple6].
|
||||||
|
func SequenceSeqTuple6[T1, T2, T3, T4, T5, T6 any](t T.Tuple6[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3], ReaderIOEither[T4], ReaderIOEither[T5], ReaderIOEither[T6]]) ReaderIOEither[T.Tuple6[T1, T2, T3, T4, T5, T6]] {
|
||||||
|
return G.SequenceSeqTuple6[ReaderIOEither[T.Tuple6[T1, T2, T3, T4, T5, T6]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceParTuple6 converts a [T.Tuple6] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple6].
|
||||||
|
func SequenceParTuple6[T1, T2, T3, T4, T5, T6 any](t T.Tuple6[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3], ReaderIOEither[T4], ReaderIOEither[T5], ReaderIOEither[T6]]) ReaderIOEither[T.Tuple6[T1, T2, T3, T4, T5, T6]] {
|
||||||
|
return G.SequenceParTuple6[ReaderIOEither[T.Tuple6[T1, T2, T3, T4, T5, T6]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseTuple6 converts a [T.Tuple6] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple6].
|
||||||
|
func TraverseTuple6[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], F4 ~func(A4) ReaderIOEither[T4], F5 ~func(A5) ReaderIOEither[T5], F6 ~func(A6) ReaderIOEither[T6], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) func(T.Tuple6[A1, A2, A3, A4, A5, A6]) ReaderIOEither[T.Tuple6[T1, T2, T3, T4, T5, T6]] {
|
||||||
|
return G.TraverseTuple6[ReaderIOEither[T.Tuple6[T1, T2, T3, T4, T5, T6]]](f1, f2, f3, f4, f5, f6)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseSeqTuple6 converts a [T.Tuple6] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple6].
|
||||||
|
func TraverseSeqTuple6[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], F4 ~func(A4) ReaderIOEither[T4], F5 ~func(A5) ReaderIOEither[T5], F6 ~func(A6) ReaderIOEither[T6], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) func(T.Tuple6[A1, A2, A3, A4, A5, A6]) ReaderIOEither[T.Tuple6[T1, T2, T3, T4, T5, T6]] {
|
||||||
|
return G.TraverseSeqTuple6[ReaderIOEither[T.Tuple6[T1, T2, T3, T4, T5, T6]]](f1, f2, f3, f4, f5, f6)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseParTuple6 converts a [T.Tuple6] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple6].
|
||||||
|
func TraverseParTuple6[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], F4 ~func(A4) ReaderIOEither[T4], F5 ~func(A5) ReaderIOEither[T5], F6 ~func(A6) ReaderIOEither[T6], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) func(T.Tuple6[A1, A2, A3, A4, A5, A6]) ReaderIOEither[T.Tuple6[T1, T2, T3, T4, T5, T6]] {
|
||||||
|
return G.TraverseParTuple6[ReaderIOEither[T.Tuple6[T1, T2, T3, T4, T5, T6]]](f1, f2, f3, f4, f5, f6)
|
||||||
|
}
|
||||||
|
|
||||||
// Eitherize7 converts a function with 7 parameters returning a tuple into a function with 7 parameters returning a [ReaderIOEither[R]]
|
// Eitherize7 converts a function with 7 parameters returning a tuple into a function with 7 parameters returning a [ReaderIOEither[R]]
|
||||||
// The inverse function is [Uneitherize7]
|
// The inverse function is [Uneitherize7]
|
||||||
func Eitherize7[F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6) (R, error), T0, T1, T2, T3, T4, T5, T6, R any](f F) func(T0, T1, T2, T3, T4, T5, T6) ReaderIOEither[R] {
|
func Eitherize7[F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6) (R, error), T0, T1, T2, T3, T4, T5, T6, R any](f F) func(T0, T1, T2, T3, T4, T5, T6) ReaderIOEither[R] {
|
||||||
return G.Eitherize7[ReaderIOEither[R]](f)
|
return G.Eitherize7[ReaderIOEither[R]](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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceSeqT7 converts 7 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple7].
|
||||||
|
func SequenceSeqT7[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.SequenceSeqT7[ReaderIOEither[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]]](t1, t2, t3, t4, t5, t6, t7)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceParT7 converts 7 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple7].
|
||||||
|
func SequenceParT7[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.SequenceParT7[ReaderIOEither[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]]](t1, t2, t3, t4, t5, t6, t7)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceTuple7 converts a [T.Tuple7] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple7].
|
||||||
|
func SequenceTuple7[T1, T2, T3, T4, T5, T6, T7 any](t T.Tuple7[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3], ReaderIOEither[T4], ReaderIOEither[T5], ReaderIOEither[T6], ReaderIOEither[T7]]) ReaderIOEither[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]] {
|
||||||
|
return G.SequenceTuple7[ReaderIOEither[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceSeqTuple7 converts a [T.Tuple7] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple7].
|
||||||
|
func SequenceSeqTuple7[T1, T2, T3, T4, T5, T6, T7 any](t T.Tuple7[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3], ReaderIOEither[T4], ReaderIOEither[T5], ReaderIOEither[T6], ReaderIOEither[T7]]) ReaderIOEither[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]] {
|
||||||
|
return G.SequenceSeqTuple7[ReaderIOEither[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceParTuple7 converts a [T.Tuple7] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple7].
|
||||||
|
func SequenceParTuple7[T1, T2, T3, T4, T5, T6, T7 any](t T.Tuple7[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3], ReaderIOEither[T4], ReaderIOEither[T5], ReaderIOEither[T6], ReaderIOEither[T7]]) ReaderIOEither[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]] {
|
||||||
|
return G.SequenceParTuple7[ReaderIOEither[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseTuple7 converts a [T.Tuple7] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple7].
|
||||||
|
func TraverseTuple7[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], F4 ~func(A4) ReaderIOEither[T4], F5 ~func(A5) ReaderIOEither[T5], F6 ~func(A6) ReaderIOEither[T6], F7 ~func(A7) ReaderIOEither[T7], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) func(T.Tuple7[A1, A2, A3, A4, A5, A6, A7]) ReaderIOEither[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]] {
|
||||||
|
return G.TraverseTuple7[ReaderIOEither[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]]](f1, f2, f3, f4, f5, f6, f7)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseSeqTuple7 converts a [T.Tuple7] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple7].
|
||||||
|
func TraverseSeqTuple7[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], F4 ~func(A4) ReaderIOEither[T4], F5 ~func(A5) ReaderIOEither[T5], F6 ~func(A6) ReaderIOEither[T6], F7 ~func(A7) ReaderIOEither[T7], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) func(T.Tuple7[A1, A2, A3, A4, A5, A6, A7]) ReaderIOEither[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]] {
|
||||||
|
return G.TraverseSeqTuple7[ReaderIOEither[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]]](f1, f2, f3, f4, f5, f6, f7)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseParTuple7 converts a [T.Tuple7] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple7].
|
||||||
|
func TraverseParTuple7[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], F4 ~func(A4) ReaderIOEither[T4], F5 ~func(A5) ReaderIOEither[T5], F6 ~func(A6) ReaderIOEither[T6], F7 ~func(A7) ReaderIOEither[T7], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) func(T.Tuple7[A1, A2, A3, A4, A5, A6, A7]) ReaderIOEither[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]] {
|
||||||
|
return G.TraverseParTuple7[ReaderIOEither[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]]](f1, f2, f3, f4, f5, f6, f7)
|
||||||
|
}
|
||||||
|
|
||||||
// Eitherize8 converts a function with 8 parameters returning a tuple into a function with 8 parameters returning a [ReaderIOEither[R]]
|
// Eitherize8 converts a function with 8 parameters returning a tuple into a function with 8 parameters returning a [ReaderIOEither[R]]
|
||||||
// The inverse function is [Uneitherize8]
|
// The inverse function is [Uneitherize8]
|
||||||
func Eitherize8[F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7) (R, error), T0, T1, T2, T3, T4, T5, T6, T7, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7) ReaderIOEither[R] {
|
func Eitherize8[F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7) (R, error), T0, T1, T2, T3, T4, T5, T6, T7, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7) ReaderIOEither[R] {
|
||||||
return G.Eitherize8[ReaderIOEither[R]](f)
|
return G.Eitherize8[ReaderIOEither[R]](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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceSeqT8 converts 8 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple8].
|
||||||
|
func SequenceSeqT8[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.SequenceSeqT8[ReaderIOEither[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]](t1, t2, t3, t4, t5, t6, t7, t8)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceParT8 converts 8 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple8].
|
||||||
|
func SequenceParT8[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.SequenceParT8[ReaderIOEither[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]](t1, t2, t3, t4, t5, t6, t7, t8)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceTuple8 converts a [T.Tuple8] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple8].
|
||||||
|
func SequenceTuple8[T1, T2, T3, T4, T5, T6, T7, T8 any](t T.Tuple8[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3], ReaderIOEither[T4], ReaderIOEither[T5], ReaderIOEither[T6], ReaderIOEither[T7], ReaderIOEither[T8]]) ReaderIOEither[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]] {
|
||||||
|
return G.SequenceTuple8[ReaderIOEither[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceSeqTuple8 converts a [T.Tuple8] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple8].
|
||||||
|
func SequenceSeqTuple8[T1, T2, T3, T4, T5, T6, T7, T8 any](t T.Tuple8[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3], ReaderIOEither[T4], ReaderIOEither[T5], ReaderIOEither[T6], ReaderIOEither[T7], ReaderIOEither[T8]]) ReaderIOEither[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]] {
|
||||||
|
return G.SequenceSeqTuple8[ReaderIOEither[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceParTuple8 converts a [T.Tuple8] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple8].
|
||||||
|
func SequenceParTuple8[T1, T2, T3, T4, T5, T6, T7, T8 any](t T.Tuple8[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3], ReaderIOEither[T4], ReaderIOEither[T5], ReaderIOEither[T6], ReaderIOEither[T7], ReaderIOEither[T8]]) ReaderIOEither[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]] {
|
||||||
|
return G.SequenceParTuple8[ReaderIOEither[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseTuple8 converts a [T.Tuple8] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple8].
|
||||||
|
func TraverseTuple8[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], F4 ~func(A4) ReaderIOEither[T4], F5 ~func(A5) ReaderIOEither[T5], F6 ~func(A6) ReaderIOEither[T6], F7 ~func(A7) ReaderIOEither[T7], F8 ~func(A8) ReaderIOEither[T8], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) func(T.Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]) ReaderIOEither[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]] {
|
||||||
|
return G.TraverseTuple8[ReaderIOEither[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]](f1, f2, f3, f4, f5, f6, f7, f8)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseSeqTuple8 converts a [T.Tuple8] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple8].
|
||||||
|
func TraverseSeqTuple8[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], F4 ~func(A4) ReaderIOEither[T4], F5 ~func(A5) ReaderIOEither[T5], F6 ~func(A6) ReaderIOEither[T6], F7 ~func(A7) ReaderIOEither[T7], F8 ~func(A8) ReaderIOEither[T8], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) func(T.Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]) ReaderIOEither[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]] {
|
||||||
|
return G.TraverseSeqTuple8[ReaderIOEither[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]](f1, f2, f3, f4, f5, f6, f7, f8)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseParTuple8 converts a [T.Tuple8] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple8].
|
||||||
|
func TraverseParTuple8[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], F4 ~func(A4) ReaderIOEither[T4], F5 ~func(A5) ReaderIOEither[T5], F6 ~func(A6) ReaderIOEither[T6], F7 ~func(A7) ReaderIOEither[T7], F8 ~func(A8) ReaderIOEither[T8], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) func(T.Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]) ReaderIOEither[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]] {
|
||||||
|
return G.TraverseParTuple8[ReaderIOEither[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]](f1, f2, f3, f4, f5, f6, f7, f8)
|
||||||
|
}
|
||||||
|
|
||||||
// Eitherize9 converts a function with 9 parameters returning a tuple into a function with 9 parameters returning a [ReaderIOEither[R]]
|
// Eitherize9 converts a function with 9 parameters returning a tuple into a function with 9 parameters returning a [ReaderIOEither[R]]
|
||||||
// The inverse function is [Uneitherize9]
|
// The inverse function is [Uneitherize9]
|
||||||
func Eitherize9[F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8) (R, error), T0, T1, T2, T3, T4, T5, T6, T7, T8, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8) ReaderIOEither[R] {
|
func Eitherize9[F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8) (R, error), T0, T1, T2, T3, T4, T5, T6, T7, T8, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8) ReaderIOEither[R] {
|
||||||
return G.Eitherize9[ReaderIOEither[R]](f)
|
return G.Eitherize9[ReaderIOEither[R]](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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceSeqT9 converts 9 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple9].
|
||||||
|
func SequenceSeqT9[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.SequenceSeqT9[ReaderIOEither[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]](t1, t2, t3, t4, t5, t6, t7, t8, t9)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceParT9 converts 9 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple9].
|
||||||
|
func SequenceParT9[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.SequenceParT9[ReaderIOEither[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]](t1, t2, t3, t4, t5, t6, t7, t8, t9)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceTuple9 converts a [T.Tuple9] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple9].
|
||||||
|
func SequenceTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t T.Tuple9[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3], ReaderIOEither[T4], ReaderIOEither[T5], ReaderIOEither[T6], ReaderIOEither[T7], ReaderIOEither[T8], ReaderIOEither[T9]]) ReaderIOEither[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]] {
|
||||||
|
return G.SequenceTuple9[ReaderIOEither[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceSeqTuple9 converts a [T.Tuple9] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple9].
|
||||||
|
func SequenceSeqTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t T.Tuple9[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3], ReaderIOEither[T4], ReaderIOEither[T5], ReaderIOEither[T6], ReaderIOEither[T7], ReaderIOEither[T8], ReaderIOEither[T9]]) ReaderIOEither[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]] {
|
||||||
|
return G.SequenceSeqTuple9[ReaderIOEither[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceParTuple9 converts a [T.Tuple9] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple9].
|
||||||
|
func SequenceParTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t T.Tuple9[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3], ReaderIOEither[T4], ReaderIOEither[T5], ReaderIOEither[T6], ReaderIOEither[T7], ReaderIOEither[T8], ReaderIOEither[T9]]) ReaderIOEither[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]] {
|
||||||
|
return G.SequenceParTuple9[ReaderIOEither[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseTuple9 converts a [T.Tuple9] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple9].
|
||||||
|
func TraverseTuple9[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], F4 ~func(A4) ReaderIOEither[T4], F5 ~func(A5) ReaderIOEither[T5], F6 ~func(A6) ReaderIOEither[T6], F7 ~func(A7) ReaderIOEither[T7], F8 ~func(A8) ReaderIOEither[T8], F9 ~func(A9) ReaderIOEither[T9], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8, A9, T9 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) func(T.Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]) ReaderIOEither[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]] {
|
||||||
|
return G.TraverseTuple9[ReaderIOEither[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]](f1, f2, f3, f4, f5, f6, f7, f8, f9)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseSeqTuple9 converts a [T.Tuple9] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple9].
|
||||||
|
func TraverseSeqTuple9[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], F4 ~func(A4) ReaderIOEither[T4], F5 ~func(A5) ReaderIOEither[T5], F6 ~func(A6) ReaderIOEither[T6], F7 ~func(A7) ReaderIOEither[T7], F8 ~func(A8) ReaderIOEither[T8], F9 ~func(A9) ReaderIOEither[T9], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8, A9, T9 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) func(T.Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]) ReaderIOEither[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]] {
|
||||||
|
return G.TraverseSeqTuple9[ReaderIOEither[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]](f1, f2, f3, f4, f5, f6, f7, f8, f9)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseParTuple9 converts a [T.Tuple9] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple9].
|
||||||
|
func TraverseParTuple9[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], F4 ~func(A4) ReaderIOEither[T4], F5 ~func(A5) ReaderIOEither[T5], F6 ~func(A6) ReaderIOEither[T6], F7 ~func(A7) ReaderIOEither[T7], F8 ~func(A8) ReaderIOEither[T8], F9 ~func(A9) ReaderIOEither[T9], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8, A9, T9 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) func(T.Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]) ReaderIOEither[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]] {
|
||||||
|
return G.TraverseParTuple9[ReaderIOEither[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]](f1, f2, f3, f4, f5, f6, f7, f8, f9)
|
||||||
|
}
|
||||||
|
|
||||||
// Eitherize10 converts a function with 10 parameters returning a tuple into a function with 10 parameters returning a [ReaderIOEither[R]]
|
// Eitherize10 converts a function with 10 parameters returning a tuple into a function with 10 parameters returning a [ReaderIOEither[R]]
|
||||||
// The inverse function is [Uneitherize10]
|
// The inverse function is [Uneitherize10]
|
||||||
func Eitherize10[F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (R, error), T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) ReaderIOEither[R] {
|
func Eitherize10[F ~func(context.Context, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (R, error), T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) ReaderIOEither[R] {
|
||||||
return G.Eitherize10[ReaderIOEither[R]](f)
|
return G.Eitherize10[ReaderIOEither[R]](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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceSeqT10 converts 10 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple10].
|
||||||
|
func SequenceSeqT10[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.SequenceSeqT10[ReaderIOEither[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]](t1, t2, t3, t4, t5, t6, t7, t8, t9, t10)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceParT10 converts 10 [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple10].
|
||||||
|
func SequenceParT10[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.SequenceParT10[ReaderIOEither[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]](t1, t2, t3, t4, t5, t6, t7, t8, t9, t10)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceTuple10 converts a [T.Tuple10] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple10].
|
||||||
|
func SequenceTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t T.Tuple10[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3], ReaderIOEither[T4], ReaderIOEither[T5], ReaderIOEither[T6], ReaderIOEither[T7], ReaderIOEither[T8], ReaderIOEither[T9], ReaderIOEither[T10]]) ReaderIOEither[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]] {
|
||||||
|
return G.SequenceTuple10[ReaderIOEither[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceSeqTuple10 converts a [T.Tuple10] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple10].
|
||||||
|
func SequenceSeqTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t T.Tuple10[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3], ReaderIOEither[T4], ReaderIOEither[T5], ReaderIOEither[T6], ReaderIOEither[T7], ReaderIOEither[T8], ReaderIOEither[T9], ReaderIOEither[T10]]) ReaderIOEither[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]] {
|
||||||
|
return G.SequenceSeqTuple10[ReaderIOEither[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceParTuple10 converts a [T.Tuple10] of [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple10].
|
||||||
|
func SequenceParTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t T.Tuple10[ReaderIOEither[T1], ReaderIOEither[T2], ReaderIOEither[T3], ReaderIOEither[T4], ReaderIOEither[T5], ReaderIOEither[T6], ReaderIOEither[T7], ReaderIOEither[T8], ReaderIOEither[T9], ReaderIOEither[T10]]) ReaderIOEither[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]] {
|
||||||
|
return G.SequenceParTuple10[ReaderIOEither[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]](t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseTuple10 converts a [T.Tuple10] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple10].
|
||||||
|
func TraverseTuple10[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], F4 ~func(A4) ReaderIOEither[T4], F5 ~func(A5) ReaderIOEither[T5], F6 ~func(A6) ReaderIOEither[T6], F7 ~func(A7) ReaderIOEither[T7], F8 ~func(A8) ReaderIOEither[T8], F9 ~func(A9) ReaderIOEither[T9], F10 ~func(A10) ReaderIOEither[T10], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8, A9, T9, A10, T10 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) func(T.Tuple10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10]) ReaderIOEither[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]] {
|
||||||
|
return G.TraverseTuple10[ReaderIOEither[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]](f1, f2, f3, f4, f5, f6, f7, f8, f9, f10)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseSeqTuple10 converts a [T.Tuple10] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple10].
|
||||||
|
func TraverseSeqTuple10[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], F4 ~func(A4) ReaderIOEither[T4], F5 ~func(A5) ReaderIOEither[T5], F6 ~func(A6) ReaderIOEither[T6], F7 ~func(A7) ReaderIOEither[T7], F8 ~func(A8) ReaderIOEither[T8], F9 ~func(A9) ReaderIOEither[T9], F10 ~func(A10) ReaderIOEither[T10], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8, A9, T9, A10, T10 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) func(T.Tuple10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10]) ReaderIOEither[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]] {
|
||||||
|
return G.TraverseSeqTuple10[ReaderIOEither[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]](f1, f2, f3, f4, f5, f6, f7, f8, f9, f10)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraverseParTuple10 converts a [T.Tuple10] of [A] via transformer functions transforming [A] to a [ReaderIOEither] into a [ReaderIOEither] of a [T.Tuple10].
|
||||||
|
func TraverseParTuple10[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], F4 ~func(A4) ReaderIOEither[T4], F5 ~func(A5) ReaderIOEither[T5], F6 ~func(A6) ReaderIOEither[T6], F7 ~func(A7) ReaderIOEither[T7], F8 ~func(A8) ReaderIOEither[T8], F9 ~func(A9) ReaderIOEither[T9], F10 ~func(A10) ReaderIOEither[T10], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8, A9, T9, A10, T10 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) func(T.Tuple10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10]) ReaderIOEither[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]] {
|
||||||
|
return G.TraverseParTuple10[ReaderIOEither[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]](f1, f2, f3, f4, f5, f6, f7, f8, f9, f10)
|
||||||
|
}
|
||||||
|
53
context/readerioeither/generic/bracket.go
Normal file
53
context/readerioeither/generic/bracket.go
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
// 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"
|
||||||
|
|
||||||
|
E "github.com/IBM/fp-go/either"
|
||||||
|
G "github.com/IBM/fp-go/internal/bracket"
|
||||||
|
I "github.com/IBM/fp-go/readerio/generic"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Bracket makes sure that a resource is cleaned up in the event of an error. The release action is called regardless of
|
||||||
|
// whether the body action returns and error or not.
|
||||||
|
func Bracket[
|
||||||
|
GA ~func(context.Context) TA,
|
||||||
|
GB ~func(context.Context) TB,
|
||||||
|
GANY ~func(context.Context) TANY,
|
||||||
|
|
||||||
|
TA ~func() E.Either[error, A],
|
||||||
|
TB ~func() E.Either[error, B],
|
||||||
|
TANY ~func() E.Either[error, ANY],
|
||||||
|
|
||||||
|
A, B, ANY any](
|
||||||
|
|
||||||
|
acquire GA,
|
||||||
|
use func(A) GB,
|
||||||
|
release func(A, E.Either[error, B]) GANY,
|
||||||
|
) GB {
|
||||||
|
return G.Bracket[GA, GB, GANY, E.Either[error, B], A, B](
|
||||||
|
I.Of[GB, TB, context.Context, E.Either[error, B]],
|
||||||
|
MonadChain[GA, GB, TA, TB, A, B],
|
||||||
|
I.MonadChain[GB, GB, TB, TB, context.Context, E.Either[error, B], E.Either[error, B]],
|
||||||
|
MonadChain[GANY, GB, TANY, TB, ANY, B],
|
||||||
|
|
||||||
|
acquire,
|
||||||
|
use,
|
||||||
|
release,
|
||||||
|
)
|
||||||
|
}
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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
|
package generic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
|
// 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
|
package generic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user