mirror of
https://github.com/IBM/fp-go.git
synced 2025-08-10 22:31:32 +02:00
Merge pull request #26 from IBM/cleue-more-samples
fix: add array examples
This commit is contained in:
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}}]
|
||||||
|
|
||||||
|
}
|
@@ -45,3 +45,12 @@ func SortByKey[GA ~[]T, K, T any](ord O.Ord[K], f func(T) K) func(ma GA) GA {
|
|||||||
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],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@@ -29,3 +29,8 @@ func Sort[T any](ord O.Ord[T]) func(ma []T) []T {
|
|||||||
func SortByKey[K, T any](ord O.Ord[K], f func(T) K) func(ma []T) []T {
|
func SortByKey[K, T any](ord O.Ord[K], f func(T) K) func(ma []T) []T {
|
||||||
return G.SortByKey[[]T](ord, f)
|
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)
|
||||||
|
}
|
||||||
|
38
option/ord.go
Normal file
38
option/ord.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 option
|
||||||
|
|
||||||
|
import (
|
||||||
|
C "github.com/IBM/fp-go/constraints"
|
||||||
|
F "github.com/IBM/fp-go/function"
|
||||||
|
"github.com/IBM/fp-go/ord"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constructs an order for [Option]
|
||||||
|
func Ord[A any](a ord.Ord[A]) ord.Ord[Option[A]] {
|
||||||
|
// some convenient shortcuts
|
||||||
|
fld := Fold(
|
||||||
|
F.Constant(Fold(F.Constant(0), F.Constant1[A](-1))),
|
||||||
|
F.Flow2(F.Curry2(a.Compare), F.Bind1st(Fold[A, int], F.Constant(1))),
|
||||||
|
)
|
||||||
|
// convert to an ordering predicate
|
||||||
|
return ord.MakeOrd(F.Uncurry2(fld), Eq(ord.ToEq(a)).Equals)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromStrictCompare constructs an [Ord] from the canonical comparison function
|
||||||
|
func FromStrictCompare[A C.Ordered]() ord.Ord[Option[A]] {
|
||||||
|
return Ord(ord.FromStrictCompare[A]())
|
||||||
|
}
|
46
option/ord_test.go
Normal file
46
option/ord_test.go
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
// 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 option
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
S "github.com/IBM/fp-go/string"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
// it('getOrd', () => {
|
||||||
|
// const OS = _.getOrd(S.Ord)
|
||||||
|
// U.deepStrictEqual(OS.compare(_.none, _.none), 0)
|
||||||
|
// U.deepStrictEqual(OS.compare(_.some('a'), _.none), 1)
|
||||||
|
// U.deepStrictEqual(OS.compare(_.none, _.some('a')), -1)
|
||||||
|
// U.deepStrictEqual(OS.compare(_.some('a'), _.some('a')), 0)
|
||||||
|
// U.deepStrictEqual(OS.compare(_.some('a'), _.some('b')), -1)
|
||||||
|
// U.deepStrictEqual(OS.compare(_.some('b'), _.some('a')), 1)
|
||||||
|
// })
|
||||||
|
|
||||||
|
func TestOrd(t *testing.T) {
|
||||||
|
|
||||||
|
os := Ord(S.Ord)
|
||||||
|
|
||||||
|
assert.Equal(t, 0, os.Compare(None[string](), None[string]()))
|
||||||
|
assert.Equal(t, 1, os.Compare(Some("a"), None[string]()))
|
||||||
|
assert.Equal(t, -1, os.Compare(None[string](), Some("a")))
|
||||||
|
assert.Equal(t, 0, os.Compare(Some("a"), Some("a")))
|
||||||
|
assert.Equal(t, -1, os.Compare(Some("a"), Some("b")))
|
||||||
|
assert.Equal(t, 1, os.Compare(Some("b"), Some("a")))
|
||||||
|
|
||||||
|
}
|
@@ -40,6 +40,11 @@ func (self ord[T]) Compare(x, y T) int {
|
|||||||
return self.c(x, y)
|
return self.c(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToEq converts an [Ord] to [E.Eq]
|
||||||
|
func ToEq[T any](o Ord[T]) E.Eq[T] {
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
// MakeOrd creates an instance of an Ord
|
// MakeOrd creates an instance of an Ord
|
||||||
func MakeOrd[T any](c func(x, y T) int, e func(x, y T) bool) Ord[T] {
|
func MakeOrd[T any](c func(x, y T) int, e func(x, y T) bool) Ord[T] {
|
||||||
return ord[T]{c: c, e: e}
|
return ord[T]{c: c, e: e}
|
||||||
|
Reference in New Issue
Block a user