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

fix: order of parameters on Ap

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
This commit is contained in:
Dr. Carsten Leue
2023-07-14 13:20:00 +02:00
parent e42d399509
commit e350f70659
31 changed files with 373 additions and 231 deletions

View File

@@ -168,12 +168,12 @@ func Chain[A, B any](f func(a A) []B) func([]A) []B {
return F.Bind2nd(MonadChain[A, B], f)
}
func MonadAp[A, B 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))
}
func Ap[A, B any](fa []A) func([]func(A) B) []B {
return F.Bind2nd(MonadAp[A, B], fa)
func Ap[B, A any](fa []A) func([]func(A) B) []B {
return F.Bind2nd(MonadAp[B, A], fa)
}
func Match[A, B any](onEmpty func() B, onNonEmpty func([]A) B) func([]A) B {

View File

@@ -38,6 +38,6 @@ func ArrayOption[A any]() func([]O.Option[A]) O.Option[[]A] {
return Sequence(
O.Of[[]A],
O.MonadMap[[]A, func(A) []A],
O.MonadAp[A, []A],
O.MonadAp[[]A, A],
)
}

View File

@@ -14,7 +14,7 @@ func TestTraverse(t *testing.T) {
traverse := Traverse(
O.Of[ArrayType],
O.MonadMap[ArrayType, func(int) ArrayType],
O.MonadAp[int, ArrayType],
O.MonadAp[ArrayType, int],
func(n int) O.Option[int] {
if n%2 == 0 {

View File

@@ -15,14 +15,17 @@ func generateSequenceT(f *os.File, i int) {
fmt.Fprintf(f, "// The function takes %d higher higher kinded types and returns a higher kinded type of a [Tuple%d] with the resolved values.\n", i, i)
fmt.Fprintf(f, "func SequenceT%d[\n", i)
// map as the starting point
fmt.Fprintf(f, " MAP ~func(HKT_T1,")
fmt.Fprintf(f, " MAP ~func(")
for j := 0; j < i; j++ {
fmt.Fprintf(f, " func(T%d)", j+1)
if j > 0 {
fmt.Fprintf(f, " ")
}
fmt.Fprintf(f, "func(T%d)", j+1)
}
fmt.Fprintf(f, " ")
fmt.Fprintf(f, "T.")
writeTupleType(f, i)
fmt.Fprintf(f, ")")
fmt.Fprintf(f, ") func(HKT_T1)")
if i > 1 {
fmt.Fprintf(f, " HKT_F")
for k := 1; k < i; k++ {
@@ -35,11 +38,12 @@ func generateSequenceT(f *os.File, i int) {
// the applicatives
for j := 1; j < i; j++ {
fmt.Fprintf(f, " AP%d ~func(", j)
fmt.Fprintf(f, "HKT_T%d) func(", j+1)
fmt.Fprintf(f, "HKT_F")
for k := j; k < i; k++ {
fmt.Fprintf(f, "_T%d", k+1)
}
fmt.Fprintf(f, ", HKT_T%d)", j+1)
fmt.Fprintf(f, ")")
if j+1 < i {
fmt.Fprintf(f, " HKT_F")
for k := j + 1; k < i; k++ {
@@ -86,20 +90,20 @@ func generateSequenceT(f *os.File, i int) {
}
fmt.Fprintf(f, ") HKT_TUPLE%d {\n", i)
fmt.Fprintf(f, " r1 := fmap(t1, tupleConstructor%d[", i)
fmt.Fprintf(f, " return F.Pipe%d(\n", i)
fmt.Fprintf(f, " t1,\n")
fmt.Fprintf(f, " fmap(tupleConstructor%d[", i)
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")
for j := 1; j < i; j++ {
fmt.Fprintf(f, " r%d := fap%d(r%d, t%d)\n", j+1, j, j, j+1)
fmt.Fprintf(f, " fap%d(t%d),\n", j, j+1)
}
fmt.Fprintf(f, " return r%d\n", i)
fmt.Fprintf(f, ")\n")
fmt.Fprintf(f, "}\n")
}

View File

@@ -6,9 +6,9 @@ import (
)
func ApplySemigroup[E, A any](s S.Semigroup[A]) S.Semigroup[Either[E, A]] {
return S.ApplySemigroup(MonadMap[E, A, func(A) A], MonadAp[E, A, A], s)
return S.ApplySemigroup(MonadMap[E, A, func(A) A], MonadAp[A, E, A], s)
}
func ApplicativeMonoid[E, A any](m M.Monoid[A]) M.Monoid[Either[E, A]] {
return M.ApplicativeMonoid(Of[E, A], MonadMap[E, A, func(A) A], MonadAp[E, A, A], m)
return M.ApplicativeMonoid(Of[E, A], MonadMap[E, A, func(A) A], MonadAp[A, E, A], m)
}

View File

@@ -12,8 +12,8 @@ func TestApplySemigroup(t *testing.T) {
sg := ApplySemigroup[string](N.SemigroupSum[int]())
la := Left[string, int]("a")
lb := Left[string, int]("b")
la := Left[int]("a")
lb := Left[int]("b")
r1 := Right[string](1)
r2 := Right[string](2)
r3 := Right[string](3)
@@ -29,8 +29,8 @@ func TestApplicativeMonoid(t *testing.T) {
m := ApplicativeMonoid[string](N.MonoidSum[int]())
la := Left[string, int]("a")
lb := Left[string, int]("b")
la := Left[int]("a")
lb := Left[int]("b")
r1 := Right[string](1)
r2 := Right[string](2)
r3 := Right[string](3)
@@ -44,5 +44,5 @@ func TestApplicativeMonoid(t *testing.T) {
func TestApplicativeMonoidLaws(t *testing.T) {
m := ApplicativeMonoid[string](N.MonoidSum[int]())
M.AssertLaws(t, m)([]Either[string, int]{Left[string, int]("a"), Right[string](1)})
M.AssertLaws(t, m)([]Either[string, int]{Left[int]("a"), Right[string](1)})
}

View File

@@ -1,9 +1,11 @@
package either
import "fmt"
import (
"fmt"
)
// Either defines a data structure that logically holds either an E or an A. The flag discriminates the cases
type (
// Either defines a data structure that logically holds either an E or an A. The flag discriminates the cases
Either[E, A any] struct {
isLeft bool
left E
@@ -29,30 +31,35 @@ func (s Either[E, A]) Format(f fmt.State, c rune) {
}
}
// IsLeft tests if the either is a left value. Rather use [Fold] if you need to access the values. Inverse is [IsRight].
func IsLeft[E, A any](val Either[E, A]) bool {
return val.isLeft
}
// IsLeft tests if the either is a right value. Rather use [Fold] if you need to access the values. Inverse is [IsLeft].
func IsRight[E, A any](val Either[E, A]) bool {
return !val.isLeft
}
func Left[E, A any](value E) Either[E, A] {
// Left creates a new instance of an [Either] representing the left value.
func Left[A, E any](value E) Either[E, A] {
return Either[E, A]{isLeft: true, left: value}
}
// Right creates a new instance of an [Either] representing the right value.
func Right[E, A any](value A) Either[E, A] {
return Either[E, A]{isLeft: false, right: value}
}
// MonadFold extracts the values from an [Either] by invoking the [onLeft] callback or the [onRight] callback depending on the case
func MonadFold[E, A, B any](ma Either[E, A], onLeft func(e E) B, onRight func(a A) B) B {
if IsLeft(ma) {
if ma.isLeft {
return onLeft(ma.left)
}
return onRight(ma.right)
}
// Unwrap converts an Either into the idiomatic tuple
// Unwrap converts an [Either] into the idiomatic tuple
func Unwrap[E, A any](ma Either[E, A]) (A, E) {
return ma.right, ma.left
}

View File

@@ -10,22 +10,23 @@ import (
O "github.com/ibm/fp-go/option"
)
// Of is equivalent to [Right]
func Of[E, A any](value A) Either[E, A] {
return F.Pipe1(value, Right[E, A])
}
func FromIO[E, A any](f func() A) Either[E, A] {
func FromIO[E, IO ~func() A, A any](f IO) Either[E, A] {
return F.Pipe1(f(), Right[E, A])
}
func MonadAp[E, A, B any](fab Either[E, func(a A) B], fa Either[E, A]) Either[E, B] {
return MonadFold(fab, Left[E, B], func(ab func(A) B) Either[E, B] {
return MonadFold(fa, Left[E, B], F.Flow2(ab, Right[E, B]))
func MonadAp[B, E, A any](fab Either[E, func(a A) B], fa Either[E, A]) Either[E, B] {
return MonadFold(fab, Left[B, E], func(ab func(A) B) Either[E, B] {
return MonadFold(fa, Left[B, E], F.Flow2(ab, Right[E, B]))
})
}
func Ap[E, A, B any](fa Either[E, A]) func(fab Either[E, func(a A) B]) Either[E, B] {
return F.Bind2nd(MonadAp[E, A, B], fa)
func Ap[B, E, A any](fa Either[E, A]) func(fab Either[E, func(a A) B]) Either[E, B] {
return F.Bind2nd(MonadAp[B, E, A], fa)
}
func MonadMap[E, A, B any](fa Either[E, A], f func(a A) B) Either[E, B] {
@@ -33,12 +34,12 @@ func MonadMap[E, A, B any](fa Either[E, A], f func(a A) B) Either[E, B] {
}
func MonadBiMap[E1, E2, A, B any](fa Either[E1, A], f func(E1) E2, g func(a A) B) Either[E2, B] {
return MonadFold(fa, F.Flow2(f, Left[E2, B]), F.Flow2(g, Right[E2, B]))
return MonadFold(fa, F.Flow2(f, Left[B, E2]), F.Flow2(g, Right[E2, B]))
}
// BiMap maps a pair of functions over the two type arguments of the bifunctor.
func BiMap[E1, E2, A, B any](f func(E1) E2, g func(a A) B) func(Either[E1, A]) Either[E2, B] {
return Fold(F.Flow2(f, Left[E2, B]), F.Flow2(g, Right[E2, B]))
return Fold(F.Flow2(f, Left[B, E2]), F.Flow2(g, Right[E2, B]))
}
func MonadMapTo[E, A, B any](fa Either[E, A], b B) Either[E, B] {
@@ -50,7 +51,7 @@ func MapTo[E, A, B any](b B) func(Either[E, A]) Either[E, B] {
}
func MonadMapLeft[E, A, B any](fa Either[E, A], f func(E) B) Either[B, A] {
return MonadFold(fa, F.Flow2(f, Left[B, A]), Right[B, A])
return MonadFold(fa, F.Flow2(f, Left[A, B]), Right[B, A])
}
func Map[E, A, B any](f func(a A) B) func(fa Either[E, A]) Either[E, B] {
@@ -62,7 +63,7 @@ func MapLeft[E, A, B any](f func(E) B) func(fa Either[E, A]) Either[B, A] {
}
func MonadChain[E, A, B any](fa Either[E, A], f func(a A) Either[E, B]) Either[E, B] {
return MonadFold(fa, Left[E, B], f)
return MonadFold(fa, Left[B, E], f)
}
func MonadChainFirst[E, A, B any](ma Either[E, A], f func(a A) Either[E, B]) Either[E, A] {
@@ -105,7 +106,7 @@ func Flatten[E, A any](mma Either[E, Either[E, A]]) Either[E, A] {
func TryCatch[FA ~func() (A, error), FE func(error) E, E, A any](f FA, onThrow FE) Either[E, A] {
val, err := f()
if err != nil {
return F.Pipe2(err, onThrow, Left[E, A])
return F.Pipe2(err, onThrow, Left[A, E])
}
return F.Pipe1(val, Right[E, A])
}
@@ -127,7 +128,7 @@ func Sequence3[E, T1, T2, T3, R any](f func(T1, T2, T3) Either[E, R]) func(Eithe
}
func FromOption[E, A any](onNone func() E) func(O.Option[A]) Either[E, A] {
return O.Fold(F.Nullary2(onNone, Left[E, A]), Right[E, A])
return O.Fold(F.Nullary2(onNone, Left[A, E]), Right[E, A])
}
func ToOption[E, A any]() func(Either[E, A]) O.Option[A] {
@@ -162,7 +163,7 @@ func FromPredicate[E, A any](pred func(A) bool, onFalse func(A) E) func(A) Eithe
if pred(a) {
return Right[E](a)
}
return Left[E, A](onFalse(a))
return Left[A, E](onFalse(a))
}
}
@@ -198,7 +199,7 @@ func ToType[E, A any](onError func(any) E) func(any) Either[E, A] {
return F.Pipe2(
value,
O.ToType[A],
O.Fold(F.Nullary3(F.Constant(value), onError, Left[E, A]), Right[E, A]),
O.Fold(F.Nullary3(F.Constant(value), onError, Left[A, E]), Right[E, A]),
)
}
}
@@ -208,17 +209,17 @@ func Memoize[E, A any](val Either[E, A]) Either[E, A] {
}
func MonadSequence2[E, T1, T2, R any](e1 Either[E, T1], e2 Either[E, T2], f func(T1, T2) Either[E, R]) Either[E, R] {
return MonadFold(e1, Left[E, R], func(t1 T1) Either[E, R] {
return MonadFold(e2, Left[E, R], func(t2 T2) Either[E, R] {
return MonadFold(e1, Left[R, E], func(t1 T1) Either[E, R] {
return MonadFold(e2, Left[R, E], func(t2 T2) Either[E, R] {
return f(t1, t2)
})
})
}
func MonadSequence3[E, T1, T2, T3, R any](e1 Either[E, T1], e2 Either[E, T2], e3 Either[E, T3], f func(T1, T2, T3) Either[E, R]) Either[E, R] {
return MonadFold(e1, Left[E, R], func(t1 T1) Either[E, R] {
return MonadFold(e2, Left[E, R], func(t2 T2) Either[E, R] {
return MonadFold(e3, Left[E, R], func(t3 T3) Either[E, R] {
return MonadFold(e1, Left[R, E], func(t1 T1) Either[E, R] {
return MonadFold(e2, Left[R, E], func(t2 T2) Either[E, R] {
return MonadFold(e3, Left[R, E], func(t3 T3) Either[E, R] {
return f(t1, t2, t3)
})
})
@@ -227,5 +228,5 @@ func MonadSequence3[E, T1, T2, T3, R any](e1 Either[E, T1], e2 Either[E, T2], e3
// Swap changes the order of type parameters
func Swap[E, A any](val Either[E, A]) Either[A, E] {
return MonadFold(val, Right[A, E], Left[A, E])
return MonadFold(val, Right[A, E], Left[E, A])
}

View File

@@ -19,7 +19,7 @@ func TestDefault(t *testing.T) {
func TestIsLeft(t *testing.T) {
err := errors.New("Some error")
withError := Left[error, string](err)
withError := Left[string](err)
assert.True(t, IsLeft(withError))
assert.False(t, IsRight(withError))
@@ -37,7 +37,7 @@ func TestMapEither(t *testing.T) {
assert.Equal(t, F.Pipe1(Right[error]("abc"), Map[error](utils.StringLen)), Right[error](3))
val2 := F.Pipe1(Left[string, string]("s"), Map[string](utils.StringLen))
exp2 := Left[string, int]("s")
exp2 := Left[int]("s")
assert.Equal(t, val2, exp2)
}
@@ -45,7 +45,7 @@ func TestMapEither(t *testing.T) {
func TestUnwrapError(t *testing.T) {
a := ""
err := errors.New("Some error")
withError := Left[error, string](err)
withError := Left[string](err)
res, extracted := UnwrapError(withError)
assert.Equal(t, a, res)
@@ -65,16 +65,16 @@ func TestReduce(t *testing.T) {
func TestAp(t *testing.T) {
f := S.Size
assert.Equal(t, Right[string](3), F.Pipe1(Right[string](f), Ap[string, string, int](Right[string]("abc"))))
assert.Equal(t, Left[string, int]("maError"), F.Pipe1(Right[string](f), Ap[string, string, int](Left[string, string]("maError"))))
assert.Equal(t, Left[string, int]("mabError"), F.Pipe1(Left[string, func(string) int]("mabError"), Ap[string, string, int](Left[string, string]("maError"))))
assert.Equal(t, Right[string](3), F.Pipe1(Right[string](f), Ap[int, string, string](Right[string]("abc"))))
assert.Equal(t, Left[int]("maError"), F.Pipe1(Right[string](f), Ap[int, string, string](Left[string, string]("maError"))))
assert.Equal(t, Left[int]("mabError"), F.Pipe1(Left[func(string) int]("mabError"), Ap[int, string, string](Left[string, string]("maError"))))
}
func TestAlt(t *testing.T) {
assert.Equal(t, Right[string](1), F.Pipe1(Right[string](1), Alt(F.Constant(Right[string](2)))))
assert.Equal(t, Right[string](1), F.Pipe1(Right[string](1), Alt(F.Constant(Left[string, int]("a")))))
assert.Equal(t, Right[string](2), F.Pipe1(Left[string, int]("b"), Alt(F.Constant(Right[string](2)))))
assert.Equal(t, Left[string, int]("b"), F.Pipe1(Left[string, int]("a"), Alt(F.Constant(Left[string, int]("b")))))
assert.Equal(t, Right[string](1), F.Pipe1(Right[string](1), Alt(F.Constant(Left[int]("a")))))
assert.Equal(t, Right[string](2), F.Pipe1(Left[int]("b"), Alt(F.Constant(Right[string](2)))))
assert.Equal(t, Left[int]("b"), F.Pipe1(Left[int]("a"), Alt(F.Constant(Left[int]("b")))))
}
func TestChainFirst(t *testing.T) {
@@ -92,11 +92,11 @@ func TestChainOptionK(t *testing.T) {
return O.None[int]()
})
assert.Equal(t, Right[string](1), f(Right[string](1)))
assert.Equal(t, Left[string, int]("a"), f(Right[string](-1)))
assert.Equal(t, Left[string, int]("b"), f(Left[string, int]("b")))
assert.Equal(t, Left[int]("a"), f(Right[string](-1)))
assert.Equal(t, Left[int]("b"), f(Left[int]("b")))
}
func TestFromOption(t *testing.T) {
assert.Equal(t, Left[string, int]("none"), FromOption[string, int](F.Constant("none"))(O.None[int]()))
assert.Equal(t, Left[int]("none"), FromOption[string, int](F.Constant("none"))(O.None[int]()))
assert.Equal(t, Right[string](1), FromOption[string, int](F.Constant("none"))(O.Some(1)))
}

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-07-13 22:33:52.2075869 +0200 CEST m=+0.011616301
// 2023-07-14 13:19:40.5850892 +0200 CEST m=+0.008180901
package either

View File

@@ -12,9 +12,9 @@ func TestEq(t *testing.T) {
r2 := Of[string](1)
r3 := Of[string](2)
e1 := Left[string, int]("a")
e2 := Left[string, int]("a")
e3 := Left[string, int]("b")
e1 := Left[int]("a")
e2 := Left[int]("a")
e3 := Left[int]("b")
eq := FromStrictEquals[string, int]()

View File

@@ -11,7 +11,7 @@ func _log[E, A any](left func(string, ...any), right func(string, ...any), prefi
return Fold(
func(e E) Either[E, A] {
left("%s: %v", prefix, e)
return Left[E, A](e)
return Left[A, E](e)
},
func(a A) Either[E, A] {
right("%s: %v", prefix, a)

View File

@@ -10,7 +10,7 @@ func TraverseRecordG[GA ~map[K]A, GB ~map[K]B, K comparable, E, A, B any](f func
return RR.Traverse[GA](
Of[E, GB],
MonadMap[E, GB, func(B) GB],
MonadAp[E, B, GB],
MonadAp[GB, E, B],
f,
)
}

View File

@@ -16,7 +16,7 @@ func WithResource[E, R, A any](onCreate func() Either[E, R], onRelease func(R) E
// handle the errors
return MonadFold(
res,
Left[E, A],
Left[A, E],
func(a A) Either[E, A] {
return F.Pipe1(
released,

View File

@@ -9,15 +9,15 @@ import (
func SequenceT1[E, A any](a Either[E, A]) Either[E, T.Tuple1[A]] {
return Apply.SequenceT1(
MonadMap[E, A, T.Tuple1[A]],
Map[E, A, T.Tuple1[A]],
a,
)
}
func SequenceT2[E, A, B any](a Either[E, A], b Either[E, B]) Either[E, T.Tuple2[A, B]] {
return Apply.SequenceT2(
MonadMap[E, A, func(B) T.Tuple2[A, B]],
MonadAp[E, B, T.Tuple2[A, B]],
Map[E, A, func(B) T.Tuple2[A, B]],
Ap[T.Tuple2[A, B], E, B],
a, b,
)
@@ -25,9 +25,9 @@ func SequenceT2[E, A, B any](a Either[E, A], b Either[E, B]) Either[E, T.Tuple2[
func SequenceT3[E, A, B, C any](a Either[E, A], b Either[E, B], c Either[E, C]) Either[E, T.Tuple3[A, B, C]] {
return Apply.SequenceT3(
MonadMap[E, A, func(B) func(C) T.Tuple3[A, B, C]],
MonadAp[E, B, func(C) T.Tuple3[A, B, C]],
MonadAp[E, C, T.Tuple3[A, B, C]],
Map[E, A, func(B) func(C) T.Tuple3[A, B, C]],
Ap[func(C) T.Tuple3[A, B, C], E, B],
Ap[T.Tuple3[A, B, C], E, C],
a, b, c,
)
@@ -35,10 +35,10 @@ func SequenceT3[E, A, B, C any](a Either[E, A], b Either[E, B], c Either[E, C])
func SequenceT4[E, A, B, C, D any](a Either[E, A], b Either[E, B], c Either[E, C], d Either[E, D]) Either[E, T.Tuple4[A, B, C, D]] {
return Apply.SequenceT4(
MonadMap[E, A, func(B) func(C) func(D) T.Tuple4[A, B, C, D]],
MonadAp[E, B, func(C) func(D) T.Tuple4[A, B, C, D]],
MonadAp[E, C, func(D) T.Tuple4[A, B, C, D]],
MonadAp[E, D, T.Tuple4[A, B, C, D]],
Map[E, A, func(B) func(C) func(D) T.Tuple4[A, B, C, D]],
Ap[func(C) func(D) T.Tuple4[A, B, C, D], E, B],
Ap[func(D) T.Tuple4[A, B, C, D], E, C],
Ap[T.Tuple4[A, B, C, D], E, D],
a, b, c, d,
)

View File

@@ -45,13 +45,13 @@ func AssertLaws[E, A, B, C any](t *testing.T,
ET.MonadChain[E, A, C],
ET.MonadChain[E, B, C],
ET.MonadAp[E, A, A],
ET.MonadAp[E, A, B],
ET.MonadAp[E, B, C],
ET.MonadAp[E, A, C],
ET.MonadAp[A, E, A],
ET.MonadAp[B, E, A],
ET.MonadAp[C, E, B],
ET.MonadAp[C, E, A],
ET.MonadAp[E, func(A) B, B],
ET.MonadAp[E, func(A) B, func(A) C],
ET.MonadAp[B, E, func(A) B],
ET.MonadAp[func(A) C, E, func(A) B],
ab,
bc,

View File

@@ -17,7 +17,7 @@ func traverse[E, A, B, HKTA, HKTB, HKTRB any](
_map func(HKTB, func(B) Either[E, B]) HKTRB,
) func(Either[E, A], func(A) HKTB) HKTRB {
left := F.Flow2(Left[E, B], _of)
left := F.Flow2(Left[B, E], _of)
right := F.Bind2nd(_map, Right[E, B])
return func(ta Either[E, A], f func(A) HKTB) HKTRB {
@@ -50,5 +50,5 @@ func Sequence[E, A, HKTA, HKTRA any](
_of func(Either[E, A]) HKTRA,
_map func(HKTA, func(A) Either[E, A]) HKTRA,
) func(Either[E, HKTA]) HKTRA {
return Fold(F.Flow2(Left[E, A], _of), F.Bind2nd(_map, Right[E, A]))
return Fold(F.Flow2(Left[A, E], _of), F.Bind2nd(_map, Right[E, A]))
}

View File

@@ -20,7 +20,7 @@ func TestTraverse(t *testing.T) {
O.MonadMap[int, Either[string, int]],
)(f)
assert.Equal(t, O.Of(Left[string, int]("a")), F.Pipe1(Left[string, int]("a"), trav))
assert.Equal(t, O.Of(Left[int]("a")), F.Pipe1(Left[int]("a"), trav))
assert.Equal(t, O.None[Either[string, int]](), F.Pipe1(Right[string](1), trav))
assert.Equal(t, O.Of(Right[string](3)), F.Pipe1(Right[string](3), trav))
}
@@ -33,6 +33,6 @@ func TestSequence(t *testing.T) {
)
assert.Equal(t, O.Of(Right[string](1)), seq(Right[string](O.Of(1))))
assert.Equal(t, O.Of(Left[string, int]("a")), seq(Left[string, O.Option[int]]("a")))
assert.Equal(t, O.Of(Left[int]("a")), seq(Left[O.Option[int]]("a")))
assert.Equal(t, O.None[Either[string, int]](), seq(Right[string](O.None[int]())))
}

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-07-13 22:33:56.702075 +0200 CEST m=+0.040313201
// 2023-07-14 13:19:42.9896471 +0200 CEST m=+0.009694501
package function
// Combinations for a total of 1 arguments

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-07-13 22:33:54.31999 +0200 CEST m=+0.046543601
// 2023-07-14 13:19:41.7019184 +0200 CEST m=+0.010131401
package function
// Pipe0 takes an initial value t0 and successively applies 0 functions where the input of a function is the return value of the previous function

View File

@@ -0,0 +1,38 @@
package generic
import (
F "github.com/ibm/fp-go/function"
C "github.com/ibm/fp-go/internal/chain"
)
func MonadAp[GAB ~func(A) B, B, A any](fab GAB, fa A) B {
return fab(fa)
}
func Ap[GAB ~func(A) B, B, A any](fa A) func(GAB) B {
return F.Bind2nd(MonadAp[GAB, B, A], fa)
}
func MonadMap[GAB ~func(A) B, A, B any](fa A, f GAB) B {
return f(fa)
}
func Map[GAB ~func(A) B, A, B any](f GAB) func(A) B {
return f
}
func MonadChain[GAB ~func(A) B, A, B any](ma A, f GAB) B {
return f(ma)
}
func Chain[GAB ~func(A) B, A, B any](f GAB) func(A) B {
return f
}
func MonadChainFirst[GAB ~func(A) B, A, B any](fa A, f GAB) A {
return C.MonadChainFirst(MonadChain[func(A) A, A, A], MonadMap[func(B) A, B, A], fa, f)
}
func ChainFirst[GAB ~func(A) B, A, B any](f GAB) func(A) A {
return C.ChainFirst(MonadChain[func(A) A, A, A], MonadMap[func(B) A, B, A], f)
}

50
identity/identity.go Normal file
View File

@@ -0,0 +1,50 @@
package identity
import (
F "github.com/ibm/fp-go/function"
G "github.com/ibm/fp-go/identity/generic"
)
func MonadAp[B, A any](fab func(A) B, fa A) B {
return G.MonadAp(fab, fa)
}
func Ap[B, A any](fa A) func(func(A) B) B {
return G.Ap[func(A) B](fa)
}
func MonadMap[A, B any](fa A, f func(A) B) B {
return G.MonadMap(fa, f)
}
func Map[A, B any](f func(A) B) func(A) B {
return G.Map(f)
}
func MonadMapTo[A, B any](fa A, b B) B {
return b
}
func MapTo[A, B any](b B) func(A) B {
return F.Constant1[A](b)
}
func Of[A any](a A) A {
return a
}
func MonadChain[A, B any](ma A, f func(A) B) B {
return G.MonadChain(ma, f)
}
func Chain[A, B any](f func(A) B) func(A) B {
return G.Chain(f)
}
func MonadChainFirst[A, B any](fa A, f func(A) B) A {
return G.MonadChainFirst(fa, f)
}
func ChainFirst[A, B any](f func(A) B) func(A) A {
return G.ChainFirst(f)
}

21
identity/identity_test.go Normal file
View File

@@ -0,0 +1,21 @@
package identity
import (
"testing"
F "github.com/ibm/fp-go/function"
"github.com/ibm/fp-go/internal/utils"
"github.com/stretchr/testify/assert"
)
func TestMap(t *testing.T) {
assert.Equal(t, Of(2), F.Pipe1(1, Map(utils.Double)))
}
func TestChain(t *testing.T) {
assert.Equal(t, Of(2), F.Pipe1(1, Chain(utils.Double)))
}
func TestAp(t *testing.T) {
assert.Equal(t, Of(2), F.Pipe1(utils.Double, Ap[int, int](1)))
}

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-07-13 22:33:59.3945287 +0200 CEST m=+0.045093901
// 2023-07-14 13:19:44.2638147 +0200 CEST m=+0.009515201
package apply
@@ -17,7 +17,7 @@ func tupleConstructor1[T1 any]() func(T1) T.Tuple1[T1] {
// SequenceT1 is a utility function used to implement the sequence operation for higher kinded types based only on map and ap.
// The function takes 1 higher higher kinded types and returns a higher kinded type of a [Tuple1] with the resolved values.
func SequenceT1[
MAP ~func(HKT_T1, func(T1) T.Tuple1[T1]) HKT_TUPLE1,
MAP ~func(func(T1) T.Tuple1[T1]) func(HKT_T1) HKT_TUPLE1,
T1,
HKT_T1, // HKT[T1]
HKT_TUPLE1 any, // HKT[Tuple1[T1]]
@@ -25,8 +25,10 @@ func SequenceT1[
fmap MAP,
t1 HKT_T1,
) HKT_TUPLE1 {
r1 := fmap(t1, tupleConstructor1[T1]())
return r1
return F.Pipe1(
t1,
fmap(tupleConstructor1[T1]()),
)
}
// tupleConstructor2 returns a curried version of [T.MakeTuple2]
@@ -37,8 +39,8 @@ func tupleConstructor2[T1, T2 any]() func(T1) func(T2) T.Tuple2[T1, T2] {
// SequenceT2 is a utility function used to implement the sequence operation for higher kinded types based only on map and ap.
// The function takes 2 higher higher kinded types and returns a higher kinded type of a [Tuple2] with the resolved values.
func SequenceT2[
MAP ~func(HKT_T1, func(T1) func(T2) T.Tuple2[T1, T2]) HKT_F_T2,
AP1 ~func(HKT_F_T2, HKT_T2) HKT_TUPLE2,
MAP ~func(func(T1) func(T2) T.Tuple2[T1, T2]) func(HKT_T1) HKT_F_T2,
AP1 ~func(HKT_T2) func(HKT_F_T2) HKT_TUPLE2,
T1,
T2,
HKT_T1, // HKT[T1]
@@ -51,9 +53,11 @@ func SequenceT2[
t1 HKT_T1,
t2 HKT_T2,
) HKT_TUPLE2 {
r1 := fmap(t1, tupleConstructor2[T1, T2]())
r2 := fap1(r1, t2)
return r2
return F.Pipe2(
t1,
fmap(tupleConstructor2[T1, T2]()),
fap1(t2),
)
}
// tupleConstructor3 returns a curried version of [T.MakeTuple3]
@@ -64,9 +68,9 @@ func tupleConstructor3[T1, T2, T3 any]() func(T1) func(T2) func(T3) T.Tuple3[T1,
// SequenceT3 is a utility function used to implement the sequence operation for higher kinded types based only on map and ap.
// The function takes 3 higher higher kinded types and returns a higher kinded type of a [Tuple3] with the resolved values.
func SequenceT3[
MAP ~func(HKT_T1, func(T1) func(T2) func(T3) T.Tuple3[T1, T2, T3]) HKT_F_T2_T3,
AP1 ~func(HKT_F_T2_T3, HKT_T2) HKT_F_T3,
AP2 ~func(HKT_F_T3, HKT_T3) HKT_TUPLE3,
MAP ~func(func(T1) func(T2) func(T3) T.Tuple3[T1, T2, T3]) func(HKT_T1) HKT_F_T2_T3,
AP1 ~func(HKT_T2) func(HKT_F_T2_T3) HKT_F_T3,
AP2 ~func(HKT_T3) func(HKT_F_T3) HKT_TUPLE3,
T1,
T2,
T3,
@@ -84,10 +88,12 @@ func SequenceT3[
t2 HKT_T2,
t3 HKT_T3,
) HKT_TUPLE3 {
r1 := fmap(t1, tupleConstructor3[T1, T2, T3]())
r2 := fap1(r1, t2)
r3 := fap2(r2, t3)
return r3
return F.Pipe3(
t1,
fmap(tupleConstructor3[T1, T2, T3]()),
fap1(t2),
fap2(t3),
)
}
// tupleConstructor4 returns a curried version of [T.MakeTuple4]
@@ -98,10 +104,10 @@ func tupleConstructor4[T1, T2, T3, T4 any]() func(T1) func(T2) func(T3) func(T4)
// SequenceT4 is a utility function used to implement the sequence operation for higher kinded types based only on map and ap.
// The function takes 4 higher higher kinded types and returns a higher kinded type of a [Tuple4] with the resolved values.
func SequenceT4[
MAP ~func(HKT_T1, func(T1) func(T2) func(T3) func(T4) T.Tuple4[T1, T2, T3, T4]) HKT_F_T2_T3_T4,
AP1 ~func(HKT_F_T2_T3_T4, HKT_T2) HKT_F_T3_T4,
AP2 ~func(HKT_F_T3_T4, HKT_T3) HKT_F_T4,
AP3 ~func(HKT_F_T4, HKT_T4) HKT_TUPLE4,
MAP ~func(func(T1) func(T2) func(T3) func(T4) T.Tuple4[T1, T2, T3, T4]) func(HKT_T1) HKT_F_T2_T3_T4,
AP1 ~func(HKT_T2) func(HKT_F_T2_T3_T4) HKT_F_T3_T4,
AP2 ~func(HKT_T3) func(HKT_F_T3_T4) HKT_F_T4,
AP3 ~func(HKT_T4) func(HKT_F_T4) HKT_TUPLE4,
T1,
T2,
T3,
@@ -124,11 +130,13 @@ func SequenceT4[
t3 HKT_T3,
t4 HKT_T4,
) HKT_TUPLE4 {
r1 := fmap(t1, tupleConstructor4[T1, T2, T3, T4]())
r2 := fap1(r1, t2)
r3 := fap2(r2, t3)
r4 := fap3(r3, t4)
return r4
return F.Pipe4(
t1,
fmap(tupleConstructor4[T1, T2, T3, T4]()),
fap1(t2),
fap2(t3),
fap3(t4),
)
}
// tupleConstructor5 returns a curried version of [T.MakeTuple5]
@@ -139,11 +147,11 @@ func tupleConstructor5[T1, T2, T3, T4, T5 any]() func(T1) func(T2) func(T3) func
// SequenceT5 is a utility function used to implement the sequence operation for higher kinded types based only on map and ap.
// The function takes 5 higher higher kinded types and returns a higher kinded type of a [Tuple5] with the resolved values.
func SequenceT5[
MAP ~func(HKT_T1, func(T1) func(T2) func(T3) func(T4) func(T5) T.Tuple5[T1, T2, T3, T4, T5]) HKT_F_T2_T3_T4_T5,
AP1 ~func(HKT_F_T2_T3_T4_T5, HKT_T2) HKT_F_T3_T4_T5,
AP2 ~func(HKT_F_T3_T4_T5, HKT_T3) HKT_F_T4_T5,
AP3 ~func(HKT_F_T4_T5, HKT_T4) HKT_F_T5,
AP4 ~func(HKT_F_T5, HKT_T5) HKT_TUPLE5,
MAP ~func(func(T1) func(T2) func(T3) func(T4) func(T5) T.Tuple5[T1, T2, T3, T4, T5]) func(HKT_T1) HKT_F_T2_T3_T4_T5,
AP1 ~func(HKT_T2) func(HKT_F_T2_T3_T4_T5) HKT_F_T3_T4_T5,
AP2 ~func(HKT_T3) func(HKT_F_T3_T4_T5) HKT_F_T4_T5,
AP3 ~func(HKT_T4) func(HKT_F_T4_T5) HKT_F_T5,
AP4 ~func(HKT_T5) func(HKT_F_T5) HKT_TUPLE5,
T1,
T2,
T3,
@@ -171,12 +179,14 @@ func SequenceT5[
t4 HKT_T4,
t5 HKT_T5,
) HKT_TUPLE5 {
r1 := fmap(t1, tupleConstructor5[T1, T2, T3, T4, T5]())
r2 := fap1(r1, t2)
r3 := fap2(r2, t3)
r4 := fap3(r3, t4)
r5 := fap4(r4, t5)
return r5
return F.Pipe5(
t1,
fmap(tupleConstructor5[T1, T2, T3, T4, T5]()),
fap1(t2),
fap2(t3),
fap3(t4),
fap4(t5),
)
}
// tupleConstructor6 returns a curried version of [T.MakeTuple6]
@@ -187,12 +197,12 @@ func tupleConstructor6[T1, T2, T3, T4, T5, T6 any]() func(T1) func(T2) func(T3)
// SequenceT6 is a utility function used to implement the sequence operation for higher kinded types based only on map and ap.
// The function takes 6 higher higher kinded types and returns a higher kinded type of a [Tuple6] with the resolved values.
func SequenceT6[
MAP ~func(HKT_T1, func(T1) func(T2) func(T3) func(T4) func(T5) func(T6) T.Tuple6[T1, T2, T3, T4, T5, T6]) HKT_F_T2_T3_T4_T5_T6,
AP1 ~func(HKT_F_T2_T3_T4_T5_T6, HKT_T2) HKT_F_T3_T4_T5_T6,
AP2 ~func(HKT_F_T3_T4_T5_T6, HKT_T3) HKT_F_T4_T5_T6,
AP3 ~func(HKT_F_T4_T5_T6, HKT_T4) HKT_F_T5_T6,
AP4 ~func(HKT_F_T5_T6, HKT_T5) HKT_F_T6,
AP5 ~func(HKT_F_T6, HKT_T6) HKT_TUPLE6,
MAP ~func(func(T1) func(T2) func(T3) func(T4) func(T5) func(T6) T.Tuple6[T1, T2, T3, T4, T5, T6]) func(HKT_T1) HKT_F_T2_T3_T4_T5_T6,
AP1 ~func(HKT_T2) func(HKT_F_T2_T3_T4_T5_T6) HKT_F_T3_T4_T5_T6,
AP2 ~func(HKT_T3) func(HKT_F_T3_T4_T5_T6) HKT_F_T4_T5_T6,
AP3 ~func(HKT_T4) func(HKT_F_T4_T5_T6) HKT_F_T5_T6,
AP4 ~func(HKT_T5) func(HKT_F_T5_T6) HKT_F_T6,
AP5 ~func(HKT_T6) func(HKT_F_T6) HKT_TUPLE6,
T1,
T2,
T3,
@@ -225,13 +235,15 @@ func SequenceT6[
t5 HKT_T5,
t6 HKT_T6,
) HKT_TUPLE6 {
r1 := fmap(t1, tupleConstructor6[T1, T2, T3, T4, T5, T6]())
r2 := fap1(r1, t2)
r3 := fap2(r2, t3)
r4 := fap3(r3, t4)
r5 := fap4(r4, t5)
r6 := fap5(r5, t6)
return r6
return F.Pipe6(
t1,
fmap(tupleConstructor6[T1, T2, T3, T4, T5, T6]()),
fap1(t2),
fap2(t3),
fap3(t4),
fap4(t5),
fap5(t6),
)
}
// tupleConstructor7 returns a curried version of [T.MakeTuple7]
@@ -242,13 +254,13 @@ func tupleConstructor7[T1, T2, T3, T4, T5, T6, T7 any]() func(T1) func(T2) func(
// SequenceT7 is a utility function used to implement the sequence operation for higher kinded types based only on map and ap.
// The function takes 7 higher higher kinded types and returns a higher kinded type of a [Tuple7] with the resolved values.
func SequenceT7[
MAP ~func(HKT_T1, func(T1) func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) T.Tuple7[T1, T2, T3, T4, T5, T6, T7]) HKT_F_T2_T3_T4_T5_T6_T7,
AP1 ~func(HKT_F_T2_T3_T4_T5_T6_T7, HKT_T2) HKT_F_T3_T4_T5_T6_T7,
AP2 ~func(HKT_F_T3_T4_T5_T6_T7, HKT_T3) HKT_F_T4_T5_T6_T7,
AP3 ~func(HKT_F_T4_T5_T6_T7, HKT_T4) HKT_F_T5_T6_T7,
AP4 ~func(HKT_F_T5_T6_T7, HKT_T5) HKT_F_T6_T7,
AP5 ~func(HKT_F_T6_T7, HKT_T6) HKT_F_T7,
AP6 ~func(HKT_F_T7, HKT_T7) HKT_TUPLE7,
MAP ~func(func(T1) func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) T.Tuple7[T1, T2, T3, T4, T5, T6, T7]) func(HKT_T1) HKT_F_T2_T3_T4_T5_T6_T7,
AP1 ~func(HKT_T2) func(HKT_F_T2_T3_T4_T5_T6_T7) HKT_F_T3_T4_T5_T6_T7,
AP2 ~func(HKT_T3) func(HKT_F_T3_T4_T5_T6_T7) HKT_F_T4_T5_T6_T7,
AP3 ~func(HKT_T4) func(HKT_F_T4_T5_T6_T7) HKT_F_T5_T6_T7,
AP4 ~func(HKT_T5) func(HKT_F_T5_T6_T7) HKT_F_T6_T7,
AP5 ~func(HKT_T6) func(HKT_F_T6_T7) HKT_F_T7,
AP6 ~func(HKT_T7) func(HKT_F_T7) HKT_TUPLE7,
T1,
T2,
T3,
@@ -286,14 +298,16 @@ func SequenceT7[
t6 HKT_T6,
t7 HKT_T7,
) HKT_TUPLE7 {
r1 := fmap(t1, tupleConstructor7[T1, T2, T3, T4, T5, T6, T7]())
r2 := fap1(r1, t2)
r3 := fap2(r2, t3)
r4 := fap3(r3, t4)
r5 := fap4(r4, t5)
r6 := fap5(r5, t6)
r7 := fap6(r6, t7)
return r7
return F.Pipe7(
t1,
fmap(tupleConstructor7[T1, T2, T3, T4, T5, T6, T7]()),
fap1(t2),
fap2(t3),
fap3(t4),
fap4(t5),
fap5(t6),
fap6(t7),
)
}
// tupleConstructor8 returns a curried version of [T.MakeTuple8]
@@ -304,14 +318,14 @@ func tupleConstructor8[T1, T2, T3, T4, T5, T6, T7, T8 any]() func(T1) func(T2) f
// SequenceT8 is a utility function used to implement the sequence operation for higher kinded types based only on map and ap.
// The function takes 8 higher higher kinded types and returns a higher kinded type of a [Tuple8] with the resolved values.
func SequenceT8[
MAP ~func(HKT_T1, func(T1) func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]) HKT_F_T2_T3_T4_T5_T6_T7_T8,
AP1 ~func(HKT_F_T2_T3_T4_T5_T6_T7_T8, HKT_T2) HKT_F_T3_T4_T5_T6_T7_T8,
AP2 ~func(HKT_F_T3_T4_T5_T6_T7_T8, HKT_T3) HKT_F_T4_T5_T6_T7_T8,
AP3 ~func(HKT_F_T4_T5_T6_T7_T8, HKT_T4) HKT_F_T5_T6_T7_T8,
AP4 ~func(HKT_F_T5_T6_T7_T8, HKT_T5) HKT_F_T6_T7_T8,
AP5 ~func(HKT_F_T6_T7_T8, HKT_T6) HKT_F_T7_T8,
AP6 ~func(HKT_F_T7_T8, HKT_T7) HKT_F_T8,
AP7 ~func(HKT_F_T8, HKT_T8) HKT_TUPLE8,
MAP ~func(func(T1) func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]) func(HKT_T1) HKT_F_T2_T3_T4_T5_T6_T7_T8,
AP1 ~func(HKT_T2) func(HKT_F_T2_T3_T4_T5_T6_T7_T8) HKT_F_T3_T4_T5_T6_T7_T8,
AP2 ~func(HKT_T3) func(HKT_F_T3_T4_T5_T6_T7_T8) HKT_F_T4_T5_T6_T7_T8,
AP3 ~func(HKT_T4) func(HKT_F_T4_T5_T6_T7_T8) HKT_F_T5_T6_T7_T8,
AP4 ~func(HKT_T5) func(HKT_F_T5_T6_T7_T8) HKT_F_T6_T7_T8,
AP5 ~func(HKT_T6) func(HKT_F_T6_T7_T8) HKT_F_T7_T8,
AP6 ~func(HKT_T7) func(HKT_F_T7_T8) HKT_F_T8,
AP7 ~func(HKT_T8) func(HKT_F_T8) HKT_TUPLE8,
T1,
T2,
T3,
@@ -354,15 +368,17 @@ func SequenceT8[
t7 HKT_T7,
t8 HKT_T8,
) HKT_TUPLE8 {
r1 := fmap(t1, tupleConstructor8[T1, T2, T3, T4, T5, T6, T7, T8]())
r2 := fap1(r1, t2)
r3 := fap2(r2, t3)
r4 := fap3(r3, t4)
r5 := fap4(r4, t5)
r6 := fap5(r5, t6)
r7 := fap6(r6, t7)
r8 := fap7(r7, t8)
return r8
return F.Pipe8(
t1,
fmap(tupleConstructor8[T1, T2, T3, T4, T5, T6, T7, T8]()),
fap1(t2),
fap2(t3),
fap3(t4),
fap4(t5),
fap5(t6),
fap6(t7),
fap7(t8),
)
}
// tupleConstructor9 returns a curried version of [T.MakeTuple9]
@@ -373,15 +389,15 @@ func tupleConstructor9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any]() func(T1) func(T
// SequenceT9 is a utility function used to implement the sequence operation for higher kinded types based only on map and ap.
// The function takes 9 higher higher kinded types and returns a higher kinded type of a [Tuple9] with the resolved values.
func SequenceT9[
MAP ~func(HKT_T1, func(T1) func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) HKT_F_T2_T3_T4_T5_T6_T7_T8_T9,
AP1 ~func(HKT_F_T2_T3_T4_T5_T6_T7_T8_T9, HKT_T2) HKT_F_T3_T4_T5_T6_T7_T8_T9,
AP2 ~func(HKT_F_T3_T4_T5_T6_T7_T8_T9, HKT_T3) HKT_F_T4_T5_T6_T7_T8_T9,
AP3 ~func(HKT_F_T4_T5_T6_T7_T8_T9, HKT_T4) HKT_F_T5_T6_T7_T8_T9,
AP4 ~func(HKT_F_T5_T6_T7_T8_T9, HKT_T5) HKT_F_T6_T7_T8_T9,
AP5 ~func(HKT_F_T6_T7_T8_T9, HKT_T6) HKT_F_T7_T8_T9,
AP6 ~func(HKT_F_T7_T8_T9, HKT_T7) HKT_F_T8_T9,
AP7 ~func(HKT_F_T8_T9, HKT_T8) HKT_F_T9,
AP8 ~func(HKT_F_T9, HKT_T9) HKT_TUPLE9,
MAP ~func(func(T1) func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) func(HKT_T1) HKT_F_T2_T3_T4_T5_T6_T7_T8_T9,
AP1 ~func(HKT_T2) func(HKT_F_T2_T3_T4_T5_T6_T7_T8_T9) HKT_F_T3_T4_T5_T6_T7_T8_T9,
AP2 ~func(HKT_T3) func(HKT_F_T3_T4_T5_T6_T7_T8_T9) HKT_F_T4_T5_T6_T7_T8_T9,
AP3 ~func(HKT_T4) func(HKT_F_T4_T5_T6_T7_T8_T9) HKT_F_T5_T6_T7_T8_T9,
AP4 ~func(HKT_T5) func(HKT_F_T5_T6_T7_T8_T9) HKT_F_T6_T7_T8_T9,
AP5 ~func(HKT_T6) func(HKT_F_T6_T7_T8_T9) HKT_F_T7_T8_T9,
AP6 ~func(HKT_T7) func(HKT_F_T7_T8_T9) HKT_F_T8_T9,
AP7 ~func(HKT_T8) func(HKT_F_T8_T9) HKT_F_T9,
AP8 ~func(HKT_T9) func(HKT_F_T9) HKT_TUPLE9,
T1,
T2,
T3,
@@ -429,16 +445,18 @@ func SequenceT9[
t8 HKT_T8,
t9 HKT_T9,
) HKT_TUPLE9 {
r1 := fmap(t1, tupleConstructor9[T1, T2, T3, T4, T5, T6, T7, T8, T9]())
r2 := fap1(r1, t2)
r3 := fap2(r2, t3)
r4 := fap3(r3, t4)
r5 := fap4(r4, t5)
r6 := fap5(r5, t6)
r7 := fap6(r6, t7)
r8 := fap7(r7, t8)
r9 := fap8(r8, t9)
return r9
return F.Pipe9(
t1,
fmap(tupleConstructor9[T1, T2, T3, T4, T5, T6, T7, T8, T9]()),
fap1(t2),
fap2(t3),
fap3(t4),
fap4(t5),
fap5(t6),
fap6(t7),
fap7(t8),
fap8(t9),
)
}
// tupleConstructor10 returns a curried version of [T.MakeTuple10]
@@ -449,16 +467,16 @@ func tupleConstructor10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any]() func(T1)
// SequenceT10 is a utility function used to implement the sequence operation for higher kinded types based only on map and ap.
// The function takes 10 higher higher kinded types and returns a higher kinded type of a [Tuple10] with the resolved values.
func SequenceT10[
MAP ~func(HKT_T1, func(T1) func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]) HKT_F_T2_T3_T4_T5_T6_T7_T8_T9_T10,
AP1 ~func(HKT_F_T2_T3_T4_T5_T6_T7_T8_T9_T10, HKT_T2) HKT_F_T3_T4_T5_T6_T7_T8_T9_T10,
AP2 ~func(HKT_F_T3_T4_T5_T6_T7_T8_T9_T10, HKT_T3) HKT_F_T4_T5_T6_T7_T8_T9_T10,
AP3 ~func(HKT_F_T4_T5_T6_T7_T8_T9_T10, HKT_T4) HKT_F_T5_T6_T7_T8_T9_T10,
AP4 ~func(HKT_F_T5_T6_T7_T8_T9_T10, HKT_T5) HKT_F_T6_T7_T8_T9_T10,
AP5 ~func(HKT_F_T6_T7_T8_T9_T10, HKT_T6) HKT_F_T7_T8_T9_T10,
AP6 ~func(HKT_F_T7_T8_T9_T10, HKT_T7) HKT_F_T8_T9_T10,
AP7 ~func(HKT_F_T8_T9_T10, HKT_T8) HKT_F_T9_T10,
AP8 ~func(HKT_F_T9_T10, HKT_T9) HKT_F_T10,
AP9 ~func(HKT_F_T10, HKT_T10) HKT_TUPLE10,
MAP ~func(func(T1) func(T2) func(T3) func(T4) func(T5) func(T6) func(T7) func(T8) func(T9) func(T10) T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]) func(HKT_T1) HKT_F_T2_T3_T4_T5_T6_T7_T8_T9_T10,
AP1 ~func(HKT_T2) func(HKT_F_T2_T3_T4_T5_T6_T7_T8_T9_T10) HKT_F_T3_T4_T5_T6_T7_T8_T9_T10,
AP2 ~func(HKT_T3) func(HKT_F_T3_T4_T5_T6_T7_T8_T9_T10) HKT_F_T4_T5_T6_T7_T8_T9_T10,
AP3 ~func(HKT_T4) func(HKT_F_T4_T5_T6_T7_T8_T9_T10) HKT_F_T5_T6_T7_T8_T9_T10,
AP4 ~func(HKT_T5) func(HKT_F_T5_T6_T7_T8_T9_T10) HKT_F_T6_T7_T8_T9_T10,
AP5 ~func(HKT_T6) func(HKT_F_T6_T7_T8_T9_T10) HKT_F_T7_T8_T9_T10,
AP6 ~func(HKT_T7) func(HKT_F_T7_T8_T9_T10) HKT_F_T8_T9_T10,
AP7 ~func(HKT_T8) func(HKT_F_T8_T9_T10) HKT_F_T9_T10,
AP8 ~func(HKT_T9) func(HKT_F_T9_T10) HKT_F_T10,
AP9 ~func(HKT_T10) func(HKT_F_T10) HKT_TUPLE10,
T1,
T2,
T3,
@@ -511,15 +529,17 @@ func SequenceT10[
t9 HKT_T9,
t10 HKT_T10,
) HKT_TUPLE10 {
r1 := fmap(t1, tupleConstructor10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]())
r2 := fap1(r1, t2)
r3 := fap2(r2, t3)
r4 := fap3(r3, t4)
r5 := fap4(r4, t5)
r6 := fap5(r5, t6)
r7 := fap6(r6, t7)
r8 := fap7(r7, t8)
r9 := fap8(r8, t9)
r10 := fap9(r9, t10)
return r10
return F.Pipe10(
t1,
fmap(tupleConstructor10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]()),
fap1(t2),
fap2(t3),
fap3(t4),
fap4(t5),
fap5(t6),
fap6(t7),
fap7(t8),
fap8(t9),
fap9(t10),
)
}

View File

@@ -10,7 +10,7 @@ func TraverseArrayG[GA ~[]A, GB ~[]B, A, B any](f func(A) Option[B]) func(GA) Op
return RA.Traverse[GA](
Of[GB],
MonadMap[GB, func(B) GB],
MonadAp[B, GB],
MonadAp[GB, B],
f,
)

View File

@@ -25,14 +25,15 @@ func FromValidation[A, B any](f func(A) (B, bool)) func(A) Option[B] {
}
// MonadAp is the applicative functor of Option
func MonadAp[A, B any](fab Option[func(A) B], fa Option[A]) Option[B] {
func MonadAp[B, A any](fab Option[func(A) B], fa Option[A]) Option[B] {
return MonadFold(fab, None[B], func(ab func(A) B) Option[B] {
return MonadFold(fa, None[B], F.Flow2(ab, Some[B]))
})
}
func Ap[A, B any](fa Option[A]) func(Option[func(A) B]) Option[B] {
return F.Bind2nd(MonadAp[A, B], fa)
// Ap is the applicative functor of Option
func Ap[B, A any](fa Option[A]) func(Option[func(A) B]) Option[B] {
return F.Bind2nd(MonadAp[B, A], fa)
}
func MonadMap[A, B any](fa Option[A], f func(A) B) Option[B] {

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-07-13 22:34:01.4247214 +0200 CEST m=+0.038058501
// 2023-07-14 13:19:45.9328857 +0200 CEST m=+0.012986701
package option
// optionize converts a nullary function to an option

View File

@@ -10,7 +10,7 @@ func TraverseRecordG[GA ~map[K]A, GB ~map[K]B, K comparable, A, B any](f func(A)
return RR.Traverse[GA](
Of[GB],
MonadMap[GB, func(B) GB],
MonadAp[B, GB],
MonadAp[GB, B],
f,
)

View File

@@ -21,7 +21,7 @@ func Sequence[A, HKTA, HKTOA any](
func SequenceT1[A any](a Option[A]) Option[T.Tuple1[A]] {
return Apply.SequenceT1(
MonadMap[A, T.Tuple1[A]],
Map[A, T.Tuple1[A]],
a,
)
@@ -29,8 +29,8 @@ func SequenceT1[A any](a Option[A]) Option[T.Tuple1[A]] {
func SequenceT2[A, B any](a Option[A], b Option[B]) Option[T.Tuple2[A, B]] {
return Apply.SequenceT2(
MonadMap[A, func(B) T.Tuple2[A, B]],
MonadAp[B, T.Tuple2[A, B]],
Map[A, func(B) T.Tuple2[A, B]],
Ap[T.Tuple2[A, B], B],
a, b,
)
@@ -38,9 +38,9 @@ func SequenceT2[A, B any](a Option[A], b Option[B]) Option[T.Tuple2[A, B]] {
func SequenceT3[A, B, C any](a Option[A], b Option[B], c Option[C]) Option[T.Tuple3[A, B, C]] {
return Apply.SequenceT3(
MonadMap[A, func(B) func(C) T.Tuple3[A, B, C]],
MonadAp[B, func(C) T.Tuple3[A, B, C]],
MonadAp[C, T.Tuple3[A, B, C]],
Map[A, func(B) func(C) T.Tuple3[A, B, C]],
Ap[func(C) T.Tuple3[A, B, C], B],
Ap[T.Tuple3[A, B, C], C],
a, b, c,
)
@@ -48,10 +48,10 @@ func SequenceT3[A, B, C any](a Option[A], b Option[B], c Option[C]) Option[T.Tup
func SequenceT4[A, B, C, D any](a Option[A], b Option[B], c Option[C], d Option[D]) Option[T.Tuple4[A, B, C, D]] {
return Apply.SequenceT4(
MonadMap[A, func(B) func(C) func(D) T.Tuple4[A, B, C, D]],
MonadAp[B, func(C) func(D) T.Tuple4[A, B, C, D]],
MonadAp[C, func(D) T.Tuple4[A, B, C, D]],
MonadAp[D, T.Tuple4[A, B, C, D]],
Map[A, func(B) func(C) func(D) T.Tuple4[A, B, C, D]],
Ap[func(C) func(D) T.Tuple4[A, B, C, D], B],
Ap[func(D) T.Tuple4[A, B, C, D], C],
Ap[T.Tuple4[A, B, C, D], D],
a, b, c, d,
)

View File

@@ -45,12 +45,12 @@ func AssertLaws[A, B, C any](t *testing.T,
O.MonadChain[B, C],
O.MonadAp[A, A],
O.MonadAp[A, B],
O.MonadAp[B, C],
O.MonadAp[A, C],
O.MonadAp[B, A],
O.MonadAp[C, B],
O.MonadAp[C, A],
O.MonadAp[func(A) B, B],
O.MonadAp[func(A) B, func(A) C],
O.MonadAp[B, func(A) B],
O.MonadAp[func(A) C, func(A) B],
ab,
bc,

View File

@@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2023-07-13 22:34:03.5413159 +0200 CEST m=+0.012707901
// 2023-07-14 13:19:47.4331101 +0200 CEST m=+0.011802301
package tuple