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

Merge pull request #56 from IBM/cleue-add-flap

fix: add flap and non empty array
This commit is contained in:
Carsten Leue
2023-09-26 22:33:30 +02:00
committed by GitHub
10 changed files with 211 additions and 0 deletions

View File

@@ -308,3 +308,11 @@ func Fold[A any](m M.Monoid[A]) func([]A) A {
func Push[A any](a A) func([]A) []A { func Push[A any](a A) func([]A) []A {
return G.Push[[]A](a) return G.Push[[]A](a)
} }
func MonadFlap[A, B any](fab []func(A) B, a A) []B {
return G.MonadFlap[func(A) B, []func(A) B, []B, A, B](fab, a)
}
func Flap[A, B any](a A) func([]func(A) B) []B {
return G.Flap[func(A) B, []func(A) B, []B, A, B](a)
}

View File

@@ -18,6 +18,7 @@ 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" 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"
@@ -250,3 +251,11 @@ func Fold[AS ~[]A, A any](m M.Monoid[A]) func(AS) A {
func Push[GA ~[]A, A any](a A) func(GA) GA { func Push[GA ~[]A, A any](a A) func(GA) GA {
return F.Bind2nd(array.Push[GA, A], a) 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)
}

105
array/nonempty/array.go Normal file
View File

@@ -0,0 +1,105 @@
// 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"
)
// 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 an array 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)
}

View File

@@ -22,6 +22,7 @@ package either
import ( import (
E "github.com/IBM/fp-go/errors" E "github.com/IBM/fp-go/errors"
F "github.com/IBM/fp-go/function" F "github.com/IBM/fp-go/function"
FC "github.com/IBM/fp-go/internal/functor"
O "github.com/IBM/fp-go/option" O "github.com/IBM/fp-go/option"
) )
@@ -245,3 +246,11 @@ func MonadSequence3[E, T1, T2, T3, R any](e1 Either[E, T1], e2 Either[E, T2], e3
func Swap[E, A any](val Either[E, A]) Either[A, E] { func Swap[E, A any](val Either[E, A]) Either[A, E] {
return MonadFold(val, Right[A, E], Left[E, A]) return MonadFold(val, Right[A, E], Left[E, A])
} }
func MonadFlap[E, A, B any](fab Either[E, func(A) B], a A) Either[E, B] {
return FC.MonadFlap(MonadMap[E, func(A) B, B], fab, a)
}
func Flap[E, A, B any](a A) func(Either[E, func(A) B]) Either[E, B] {
return F.Bind2nd(MonadFlap[E, A, B], a)
}

View File

@@ -18,6 +18,7 @@ package generic
import ( import (
F "github.com/IBM/fp-go/function" F "github.com/IBM/fp-go/function"
C "github.com/IBM/fp-go/internal/chain" C "github.com/IBM/fp-go/internal/chain"
FC "github.com/IBM/fp-go/internal/functor"
) )
func MonadAp[GAB ~func(A) B, B, A any](fab GAB, fa A) B { func MonadAp[GAB ~func(A) B, B, A any](fab GAB, fa A) B {
@@ -51,3 +52,11 @@ func MonadChainFirst[GAB ~func(A) B, A, B any](fa A, f GAB) A {
func ChainFirst[GAB ~func(A) B, A, B any](f GAB) func(A) A { func ChainFirst[GAB ~func(A) B, A, B any](f GAB) func(A) A {
return C.ChainFirst(MonadChain[func(A) A, A, A], MonadMap[func(B) A, B, A], f) return C.ChainFirst(MonadChain[func(A) A, A, A], MonadMap[func(B) A, B, A], f)
} }
func MonadFlap[GAB ~func(A) B, A, B any](fab GAB, a A) B {
return FC.MonadFlap(MonadMap[func(GAB) B, GAB, B], fab, a)
}
func Flap[GAB ~func(A) B, A, B any](a A) func(GAB) B {
return F.Bind2nd(MonadFlap[GAB, A, B], a)
}

View File

@@ -63,3 +63,11 @@ func MonadChainFirst[A, B any](fa A, f func(A) B) A {
func ChainFirst[A, B any](f func(A) B) func(A) A { func ChainFirst[A, B any](f func(A) B) func(A) A {
return G.ChainFirst(f) return G.ChainFirst(f)
} }
func MonadFlap[A, B any](fab func(A) B, a A) B {
return G.MonadFlap[func(A) B](fab, a)
}
func Flap[A, B any](a A) func(func(A) B) B {
return G.Flap[func(A) B](a)
}

37
internal/functor/flap.go Normal file
View File

@@ -0,0 +1,37 @@
// Copyright (c) 2023 IBM Corp.
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package functor
func MonadFlap[FAB ~func(A) B, A, B, HKTFAB, HKTB any](
fmap func(HKTFAB, func(FAB) B) HKTB,
fab HKTFAB,
a A,
) HKTB {
return fmap(fab, func(f FAB) B {
return f(a)
})
}
func Flap[FAB ~func(A) B, A, B, HKTFAB, HKTB any](
fmap func(HKTFAB, func(FAB) B) HKTB,
a A,
) func(HKTFAB) HKTB {
return func(fab HKTFAB) HKTB {
return MonadFlap(fmap, fab, a)
}
}

View File

@@ -20,6 +20,7 @@ import (
F "github.com/IBM/fp-go/function" F "github.com/IBM/fp-go/function"
C "github.com/IBM/fp-go/internal/chain" C "github.com/IBM/fp-go/internal/chain"
FC "github.com/IBM/fp-go/internal/functor"
L "github.com/IBM/fp-go/internal/lazy" L "github.com/IBM/fp-go/internal/lazy"
) )
@@ -143,3 +144,11 @@ func Defer[GA ~func() A, A any](gen func() GA) GA {
return gen()() return gen()()
}) })
} }
func MonadFlap[FAB ~func(A) B, GFAB ~func() FAB, GB ~func() B, A, B any](fab GFAB, a A) GB {
return FC.MonadFlap(MonadMap[GFAB, GB, FAB, B], fab, a)
}
func Flap[FAB ~func(A) B, GFAB ~func() FAB, GB ~func() B, A, B any](a A) func(GFAB) GB {
return F.Bind2nd(MonadFlap[FAB, GFAB, GB, A, B], a)
}

View File

@@ -138,3 +138,11 @@ var Now = G.Now[IO[time.Time]]()
func Defer[A any](gen func() IO[A]) IO[A] { func Defer[A any](gen func() IO[A]) IO[A] {
return G.Defer[IO[A]](gen) return G.Defer[IO[A]](gen)
} }
func MonadFlap[A, B any](fab IO[func(A) B], a A) IO[B] {
return G.MonadFlap[func(A) B, IO[func(A) B], IO[B], A, B](fab, a)
}
func Flap[FAB ~func(A) B, GFAB ~func() FAB, GB ~func() B, A, B any](a A) func(IO[func(A) B]) IO[B] {
return G.Flap[func(A) B, IO[func(A) B], IO[B], A, B](a)
}

View File

@@ -18,6 +18,7 @@ package option
import ( import (
F "github.com/IBM/fp-go/function" F "github.com/IBM/fp-go/function"
FC "github.com/IBM/fp-go/internal/functor"
) )
func fromPredicate[A any](a A, pred func(A) bool) Option[A] { func fromPredicate[A any](a A, pred func(A) bool) Option[A] {
@@ -141,3 +142,11 @@ func Reduce[A, B any](f func(B, A) B, initial B) func(Option[A]) B {
func Filter[A any](pred func(A) bool) func(Option[A]) Option[A] { func Filter[A any](pred func(A) bool) func(Option[A]) Option[A] {
return Fold(None[A], F.Ternary(pred, Of[A], F.Ignore1of1[A](None[A]))) return Fold(None[A], F.Ternary(pred, Of[A], F.Ignore1of1[A](None[A])))
} }
func MonadFlap[A, B any](fab Option[func(A) B], a A) Option[B] {
return FC.MonadFlap(MonadMap[func(A) B, B], fab, a)
}
func Flap[A, B any](a A) func(Option[func(A) B]) Option[B] {
return F.Bind2nd(MonadFlap[A, B], a)
}