mirror of
https://github.com/IBM/fp-go.git
synced 2025-08-24 19:29:11 +02:00
Compare commits
22 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
a516849c07 | ||
|
29200d34dc | ||
|
7a3989989b | ||
|
6a6d53f025 | ||
|
078da752cd | ||
|
1a489fde27 | ||
|
a135b2acae | ||
|
9e9dfa1f5f | ||
|
dd87ea12b3 | ||
|
5fc0d18c97 | ||
|
76c1297576 | ||
|
68aeb4c725 | ||
|
53f3fa1828 | ||
|
97e1e4d92d | ||
|
ec57d5cd4a | ||
|
0ae5b43724 | ||
|
e73e14c0ae | ||
|
325bc376f9 | ||
|
f646ace9fe | ||
|
9f8161fbc1 | ||
|
1c4f2c0403 | ||
|
3b3b80aed0 |
12
.github/workflows/build.yml
vendored
12
.github/workflows/build.yml
vendored
@@ -18,7 +18,7 @@ env:
|
||||
# Currently no way to detect automatically
|
||||
DEFAULT_BRANCH: main
|
||||
GO_VERSION: 1.21.6 # renovate: datasource=golang-version depName=golang
|
||||
NODE_VERSION: 20
|
||||
NODE_VERSION: 22
|
||||
DRY_RUN: true
|
||||
|
||||
jobs:
|
||||
@@ -26,10 +26,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [ '1.20.x', '1.21.x', '1.22.x']
|
||||
go-version: [ '1.20.x', '1.21.x', '1.22.x', '1.23.x']
|
||||
steps:
|
||||
# full checkout for semantic-release
|
||||
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up go ${{ matrix.go-version }}
|
||||
@@ -55,12 +55,12 @@ jobs:
|
||||
steps:
|
||||
# full checkout for semantic-release
|
||||
- name: Full checkout
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Node.js ${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
@@ -82,7 +82,7 @@ jobs:
|
||||
|
||||
- name: Semantic Release
|
||||
run: |
|
||||
npx -p "conventional-changelog-conventionalcommits@<8" -p semantic-release semantic-release --dry-run ${{env.DRY_RUN}}
|
||||
npx -p conventional-changelog-conventionalcommits -p semantic-release semantic-release --dry-run ${{env.DRY_RUN}}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,4 +1,5 @@
|
||||
fp-go.exe
|
||||
fp-go
|
||||
main.exe
|
||||
build/
|
||||
.idea
|
@@ -29,9 +29,9 @@ This library aims to provide a set of data types and functions that make it easy
|
||||
|
||||
### How does this play with the [🧘🏽 Zen Of Go](https://the-zen-of-go.netlify.app/)?
|
||||
|
||||
#### 🧘🏽 Each package fulfils a single purpose
|
||||
#### 🧘🏽 Each package fulfills a single purpose
|
||||
|
||||
✔️ Each of the top level packages (e.g. Option, Either, ReaderIOEither, ...) fulfils the purpose of defining the respective data type and implementing the set of common operations for this data type.
|
||||
✔️ Each of the top level packages (e.g. Option, Either, ReaderIOEither, ...) fulfills the purpose of defining the respective data type and implementing the set of common operations for this data type.
|
||||
|
||||
#### 🧘🏽 Handle errors explicitly
|
||||
|
||||
|
8
go.mod
8
go.mod
@@ -3,15 +3,15 @@ module github.com/IBM/fp-go
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/urfave/cli/v2 v2.27.2
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/urfave/cli/v2 v2.27.6
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
18
go.sum
18
go.sum
@@ -1,5 +1,7 @@
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
@@ -8,12 +10,16 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho=
|
||||
github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
|
||||
github.com/urfave/cli/v2 v2.27.2 h1:6e0H+AkS+zDckwPCUrZkKX38mRaau4nL2uipkJpbkcI=
|
||||
github.com/urfave/cli/v2 v2.27.2/go.mod h1:g0+79LmHHATl7DAcHO99smiR/T7uGLw84w8Y42x+4eM=
|
||||
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw=
|
||||
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/urfave/cli/v2 v2.27.4 h1:o1owoI+02Eb+K107p27wEX9Bb8eqIoZCfLXloLUSWJ8=
|
||||
github.com/urfave/cli/v2 v2.27.4/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ=
|
||||
github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
|
||||
github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
|
||||
github.com/urfave/cli/v2 v2.27.6 h1:VdRdS98FNhKZ8/Az8B7MTyGQmpIr36O1EHybx/LaZ4g=
|
||||
github.com/urfave/cli/v2 v2.27.6/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
@@ -19,8 +19,7 @@ import (
|
||||
G "github.com/IBM/fp-go/iterator/stateless/generic"
|
||||
)
|
||||
|
||||
// DropWhile creates an [Iterator] that drops elements from the [Iterator] as long as the predicate is true; afterwards, returns every element.
|
||||
// Note, the [Iterator] does not produce any output until the predicate first becomes false
|
||||
// Cycle creates an [Iterator] containing an [Iterator] repeated an infinite number of times.
|
||||
func Cycle[U any](ma Iterator[U]) Iterator[U] {
|
||||
return G.Cycle[Iterator[U]](ma)
|
||||
}
|
||||
|
@@ -64,7 +64,7 @@ func Reverse[T any](o Ord[T]) Ord[T] {
|
||||
}, o.Equals)
|
||||
}
|
||||
|
||||
// Contramap creates an odering under a transformation function
|
||||
// Contramap creates an ordering under a transformation function
|
||||
func Contramap[A, B any](f func(B) A) func(Ord[A]) Ord[B] {
|
||||
return func(o Ord[A]) Ord[B] {
|
||||
return MakeOrd(func(x, y B) int {
|
||||
|
@@ -23,3 +23,8 @@ import (
|
||||
func Eq[K comparable, V any](e E.Eq[V]) E.Eq[map[K]V] {
|
||||
return G.Eq[map[K]V, K, V](e)
|
||||
}
|
||||
|
||||
// FromStrictEquals constructs an [EQ.Eq] from the canonical comparison function
|
||||
func FromStrictEquals[K, V comparable]() E.Eq[map[K]V] {
|
||||
return G.FromStrictEquals[map[K]V]()
|
||||
}
|
||||
|
48
record/eq_test.go
Normal file
48
record/eq_test.go
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright (c) 2024 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 record
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestFromStrictEquals(t *testing.T) {
|
||||
m1 := map[string]string{
|
||||
"a": "A",
|
||||
"b": "B",
|
||||
}
|
||||
m2 := map[string]string{
|
||||
"a": "A",
|
||||
"b": "C",
|
||||
}
|
||||
m3 := map[string]string{
|
||||
"a": "A",
|
||||
"b": "B",
|
||||
}
|
||||
m4 := map[string]string{
|
||||
"a": "A",
|
||||
"b": "B",
|
||||
"c": "C",
|
||||
}
|
||||
|
||||
e := FromStrictEquals[string, string]()
|
||||
assert.True(t, e.Equals(m1, m1))
|
||||
assert.True(t, e.Equals(m1, m3))
|
||||
assert.False(t, e.Equals(m1, m2))
|
||||
assert.False(t, e.Equals(m1, m4))
|
||||
}
|
@@ -37,3 +37,8 @@ func Eq[M ~map[K]V, K comparable, V any](e E.Eq[V]) E.Eq[M] {
|
||||
return equals(left, right, eq)
|
||||
})
|
||||
}
|
||||
|
||||
// FromStrictEquals constructs an [EQ.Eq] from the canonical comparison function
|
||||
func FromStrictEquals[M ~map[K]V, K, V comparable]() E.Eq[M] {
|
||||
return Eq[M](E.FromStrictEquals[V]())
|
||||
}
|
||||
|
@@ -54,3 +54,69 @@ func TestUnionMonoid(t *testing.T) {
|
||||
|
||||
assert.Equal(t, res, m.Concat(x, y))
|
||||
}
|
||||
|
||||
func TestUnionFirstMonoid(t *testing.T) {
|
||||
m := UnionFirstMonoid[string, string]()
|
||||
|
||||
e := Empty[string, string]()
|
||||
|
||||
x := map[string]string{
|
||||
"a": "a1",
|
||||
"b": "b1",
|
||||
"c": "c1",
|
||||
}
|
||||
|
||||
y := map[string]string{
|
||||
"b": "b2",
|
||||
"c": "c2",
|
||||
"d": "d2",
|
||||
}
|
||||
|
||||
res := map[string]string{
|
||||
"a": "a1",
|
||||
"b": "b1",
|
||||
"c": "c1",
|
||||
"d": "d2",
|
||||
}
|
||||
|
||||
assert.Equal(t, x, m.Concat(x, m.Empty()))
|
||||
assert.Equal(t, x, m.Concat(m.Empty(), x))
|
||||
|
||||
assert.Equal(t, x, m.Concat(x, e))
|
||||
assert.Equal(t, x, m.Concat(e, x))
|
||||
|
||||
assert.Equal(t, res, m.Concat(x, y))
|
||||
}
|
||||
|
||||
func TestUnionLastMonoid(t *testing.T) {
|
||||
m := UnionLastMonoid[string, string]()
|
||||
|
||||
e := Empty[string, string]()
|
||||
|
||||
x := map[string]string{
|
||||
"a": "a1",
|
||||
"b": "b1",
|
||||
"c": "c1",
|
||||
}
|
||||
|
||||
y := map[string]string{
|
||||
"b": "b2",
|
||||
"c": "c2",
|
||||
"d": "d2",
|
||||
}
|
||||
|
||||
res := map[string]string{
|
||||
"a": "a1",
|
||||
"b": "b2",
|
||||
"c": "c2",
|
||||
"d": "d2",
|
||||
}
|
||||
|
||||
assert.Equal(t, x, m.Concat(x, m.Empty()))
|
||||
assert.Equal(t, x, m.Concat(m.Empty(), x))
|
||||
|
||||
assert.Equal(t, x, m.Concat(x, e))
|
||||
assert.Equal(t, x, m.Concat(e, x))
|
||||
|
||||
assert.Equal(t, res, m.Concat(x, y))
|
||||
}
|
||||
|
@@ -176,3 +176,25 @@ func TestFromArrayMap(t *testing.T) {
|
||||
"C": "C",
|
||||
}, res2)
|
||||
}
|
||||
|
||||
func TestEmpty(t *testing.T) {
|
||||
nonEmpty := map[string]string{
|
||||
"a": "A",
|
||||
"b": "B",
|
||||
}
|
||||
empty := Empty[string, string]()
|
||||
|
||||
assert.True(t, IsEmpty(empty))
|
||||
assert.False(t, IsEmpty(nonEmpty))
|
||||
assert.False(t, IsNonEmpty(empty))
|
||||
assert.True(t, IsNonEmpty(nonEmpty))
|
||||
}
|
||||
|
||||
func TestHas(t *testing.T) {
|
||||
nonEmpty := map[string]string{
|
||||
"a": "A",
|
||||
"b": "B",
|
||||
}
|
||||
assert.True(t, Has("a", nonEmpty))
|
||||
assert.False(t, Has("c", nonEmpty))
|
||||
}
|
||||
|
Reference in New Issue
Block a user