2023-07-23 22:05:54 +02:00
// 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.
2023-07-07 22:31:06 +02:00
package array
import (
2023-07-18 15:57:54 +02:00
G "github.com/IBM/fp-go/array/generic"
F "github.com/IBM/fp-go/function"
"github.com/IBM/fp-go/internal/array"
M "github.com/IBM/fp-go/monoid"
O "github.com/IBM/fp-go/option"
"github.com/IBM/fp-go/tuple"
2023-07-07 22:31:06 +02:00
)
// From constructs an array from a set of variadic arguments
func From [ A any ] ( data ... A ) [ ] A {
return G . From [ [ ] A ] ( data ... )
}
// MakeBy returns a `Array` of length `n` with element `i` initialized with `f(i)`.
2023-07-20 16:17:23 +02:00
func MakeBy [ F ~ func ( int ) A , A any ] ( n int , f F ) [ ] A {
return G . MakeBy [ [ ] A ] ( n , f )
2023-07-07 22:31:06 +02:00
}
// Replicate creates a `Array` containing a value repeated the specified number of times.
func Replicate [ A any ] ( n int , a A ) [ ] A {
2023-07-20 16:17:23 +02:00
return G . Replicate [ [ ] A ] ( n , a )
2023-07-07 22:31:06 +02:00
}
func MonadMap [ A , B any ] ( as [ ] A , f func ( a A ) B ) [ ] B {
return G . MonadMap [ [ ] A , [ ] B ] ( as , f )
}
func MonadMapRef [ A , B any ] ( as [ ] A , f func ( a * A ) B ) [ ] B {
count := len ( as )
bs := make ( [ ] B , count )
for i := count - 1 ; i >= 0 ; i -- {
bs [ i ] = f ( & as [ i ] )
}
return bs
}
func Map [ A , B any ] ( f func ( a A ) B ) func ( [ ] A ) [ ] B {
return F . Bind2nd ( MonadMap [ A , B ] , f )
}
func MapRef [ A , B any ] ( f func ( a * A ) B ) func ( [ ] A ) [ ] B {
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 {
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 filterMapRef [ A , B any ] ( fa [ ] A , pred func ( a * A ) bool , f func ( a * A ) B ) [ ] B {
var result [ ] B
count := len ( fa )
for i := 0 ; i < count ; i ++ {
a := fa [ i ]
if pred ( & a ) {
result = append ( result , f ( & a ) )
}
}
return result
}
func Filter [ A any ] ( pred func ( A ) bool ) func ( [ ] A ) [ ] A {
return F . Bind2nd ( filter [ A ] , pred )
}
func FilterRef [ A any ] ( pred func ( * A ) bool ) func ( [ ] A ) [ ] A {
return F . Bind2nd ( filterRef [ A ] , pred )
}
func MonadFilterMap [ A , B any ] ( fa [ ] A , f func ( a A ) O . Option [ B ] ) [ ] B {
return G . MonadFilterMap [ [ ] A , [ ] B ] ( fa , f )
}
2023-08-10 11:46:30 +02:00
// FilterChain maps an array with an iterating function that returns an [O.Option] and it keeps only the Some values discarding the Nones.
2023-07-07 22:31:06 +02:00
func FilterMap [ A , B any ] ( f func ( a A ) O . Option [ B ] ) func ( [ ] A ) [ ] B {
return G . FilterMap [ [ ] A , [ ] B ] ( f )
}
2023-08-10 11:46:30 +02:00
// 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 )
}
2023-07-07 22:31:06 +02:00
func FilterMapRef [ A , B any ] ( pred func ( a * A ) bool , f func ( a * A ) B ) func ( [ ] A ) [ ] B {
return func ( fa [ ] A ) [ ] B {
return filterMapRef ( fa , pred , f )
}
}
func reduceRef [ A , B any ] ( fa [ ] A , f func ( B , * A ) B , initial B ) B {
current := initial
count := len ( fa )
for i := 0 ; i < count ; i ++ {
current = f ( current , & fa [ i ] )
}
return current
}
func Reduce [ A , B any ] ( f func ( B , A ) B , initial B ) func ( [ ] A ) B {
return func ( as [ ] A ) B {
return array . Reduce ( as , f , initial )
}
}
func ReduceRef [ A , B any ] ( f func ( B , * A ) B , initial B ) func ( [ ] A ) B {
return func ( as [ ] A ) B {
return reduceRef ( as , f , initial )
}
}
func Append [ A any ] ( as [ ] A , a A ) [ ] A {
return G . Append ( as , a )
}
func IsEmpty [ A any ] ( as [ ] A ) bool {
2023-07-24 16:43:07 +02:00
return G . IsEmpty ( as )
2023-07-07 22:31:06 +02:00
}
func IsNonEmpty [ A any ] ( as [ ] A ) bool {
return len ( as ) > 0
}
func Empty [ A any ] ( ) [ ] A {
return G . Empty [ [ ] A ] ( )
}
func Zero [ A any ] ( ) [ ] A {
return Empty [ A ] ( )
}
// Of constructs a single element array
func Of [ A any ] ( a A ) [ ] A {
return G . Of [ [ ] A ] ( a )
}
func MonadChain [ A , B any ] ( fa [ ] A , f func ( a A ) [ ] B ) [ ] B {
2023-07-20 16:17:23 +02:00
return G . MonadChain [ [ ] A , [ ] B ] ( fa , f )
2023-07-07 22:31:06 +02:00
}
2023-07-20 16:17:23 +02:00
func Chain [ A , B any ] ( f func ( A ) [ ] B ) func ( [ ] A ) [ ] B {
return G . Chain [ [ ] A , [ ] B ] ( f )
2023-07-07 22:31:06 +02:00
}
2023-07-14 13:20:00 +02:00
func MonadAp [ B , A any ] ( fab [ ] func ( A ) B , fa [ ] A ) [ ] B {
2023-07-20 16:17:23 +02:00
return G . MonadAp [ [ ] B ] ( fab , fa )
2023-07-07 22:31:06 +02:00
}
2023-07-14 13:20:00 +02:00
func Ap [ B , A any ] ( fa [ ] A ) func ( [ ] func ( A ) B ) [ ] B {
2023-07-20 16:17:23 +02:00
return G . Ap [ [ ] B , [ ] func ( A ) B ] ( fa )
2023-07-07 22:31:06 +02:00
}
func Match [ A , B any ] ( onEmpty func ( ) B , onNonEmpty func ( [ ] A ) B ) func ( [ ] A ) B {
2023-07-24 16:43:07 +02:00
return G . Match [ [ ] A ] ( onEmpty , onNonEmpty )
}
func MatchLeft [ A , B any ] ( onEmpty func ( ) B , onNonEmpty func ( A , [ ] A ) B ) func ( [ ] A ) B {
return G . MatchLeft [ [ ] A ] ( onEmpty , onNonEmpty )
2023-07-07 22:31:06 +02:00
}
func Tail [ A any ] ( as [ ] A ) O . Option [ [ ] A ] {
return G . Tail ( as )
}
func Head [ A any ] ( as [ ] A ) O . Option [ A ] {
return G . Head ( as )
}
func First [ A any ] ( as [ ] A ) O . Option [ A ] {
return G . First ( as )
}
func Last [ A any ] ( as [ ] A ) O . Option [ A ] {
return G . Last ( as )
}
func PrependAll [ A any ] ( middle A ) func ( [ ] A ) [ ] A {
return func ( as [ ] A ) [ ] A {
count := len ( as )
dst := count * 2
result := make ( [ ] A , dst )
for i := count - 1 ; i >= 0 ; i -- {
dst --
result [ dst ] = as [ i ]
dst --
result [ dst ] = middle
}
return result
}
}
func Intersperse [ A any ] ( middle A ) func ( [ ] A ) [ ] A {
prepend := PrependAll ( middle )
return func ( as [ ] A ) [ ] A {
if IsEmpty ( as ) {
return as
}
return prepend ( as ) [ 1 : ]
}
}
func Intercalate [ A any ] ( m M . Monoid [ A ] ) func ( A ) func ( [ ] A ) A {
2023-07-27 22:39:38 +02:00
concatAll := ConcatAll [ A ] ( m )
2023-07-07 22:31:06 +02:00
return func ( middle A ) func ( [ ] A ) A {
return Match ( m . Empty , F . Flow2 ( Intersperse ( middle ) , concatAll ) )
}
}
func Flatten [ A any ] ( mma [ ] [ ] A ) [ ] A {
2023-08-10 11:46:30 +02:00
return G . Flatten ( mma )
2023-07-07 22:31:06 +02:00
}
func Slice [ A any ] ( low , high int ) func ( as [ ] A ) [ ] A {
return array . Slice [ [ ] A ] ( low , high )
}
func Lookup [ A any ] ( idx int ) func ( [ ] A ) O . Option [ A ] {
return G . Lookup [ [ ] A ] ( idx )
}
func UpsertAt [ A any ] ( a A ) func ( [ ] A ) [ ] A {
return G . UpsertAt [ [ ] A ] ( a )
}
func Size [ A any ] ( as [ ] A ) int {
return G . Size ( as )
}
func MonadPartition [ A any ] ( as [ ] A , pred func ( A ) bool ) tuple . Tuple2 [ [ ] A , [ ] A ] {
return G . MonadPartition ( as , pred )
}
// Partition creates two new arrays out of one, the left result contains the elements
// for which the predicate returns false, the right one those for which the predicate returns true
func Partition [ A any ] ( pred func ( A ) bool ) func ( [ ] A ) tuple . Tuple2 [ [ ] A , [ ] A ] {
return G . Partition [ [ ] A ] ( pred )
}
// IsNil checks if the array is set to nil
func IsNil [ A any ] ( as [ ] A ) bool {
return array . IsNil ( as )
}
// IsNonNil checks if the array is set to nil
func IsNonNil [ A any ] ( as [ ] A ) bool {
return array . IsNonNil ( as )
}
// ConstNil returns a nil array
func ConstNil [ A any ] ( ) [ ] A {
return array . ConstNil [ [ ] A ] ( )
}
2023-07-28 22:50:52 +02:00
func SliceRight [ A any ] ( start int ) func ( [ ] A ) [ ] A {
return G . SliceRight [ [ ] A ] ( start )
}
func Copy [ A any ] ( b [ ] A ) [ ] A {
return G . Copy ( b )
}
2023-08-10 18:08:11 +02:00
// 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 )
}
// Fold folds the array using the provided Monoid.
func Fold [ A any ] ( m M . Monoid [ A ] ) func ( [ ] A ) A {
return G . Fold [ [ ] A ] ( m )
}
2023-08-24 22:49:03 +02:00
func Push [ A any ] ( a A ) func ( [ ] A ) [ ] A {
return G . Push [ [ ] A ] ( a )
}
2023-09-26 22:32:53 +02:00
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 )
}