mirror of
https://github.com/IBM/fp-go.git
synced 2025-11-27 22:28:29 +02:00
fix: linter bugs
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
This commit is contained in:
@@ -44,11 +44,11 @@ func From[A any](first A, data ...A) NonEmptyArray[A] {
|
|||||||
return buffer
|
return buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsEmpty[A any](as NonEmptyArray[A]) bool {
|
func IsEmpty[A any](_ NonEmptyArray[A]) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsNonEmpty[A any](as NonEmptyArray[A]) bool {
|
func IsNonEmpty[A any](_ NonEmptyArray[A]) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,20 +32,20 @@ type bounded[T any] struct {
|
|||||||
b T
|
b T
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self bounded[T]) Equals(x, y T) bool {
|
func (b bounded[T]) Equals(x, y T) bool {
|
||||||
return self.e(x, y)
|
return b.e(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self bounded[T]) Compare(x, y T) int {
|
func (b bounded[T]) Compare(x, y T) int {
|
||||||
return self.c(x, y)
|
return b.c(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self bounded[T]) Top() T {
|
func (b bounded[T]) Top() T {
|
||||||
return self.t
|
return b.t
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self bounded[T]) Bottom() T {
|
func (b bounded[T]) Bottom() T {
|
||||||
return self.b
|
return b.b
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeBounded creates an instance of a bounded type
|
// MakeBounded creates an instance of a bounded type
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ func Of[E, A any](m M.Monoid[E]) func(A) Const[E, A] {
|
|||||||
return F.Constant1[A](Make[E, A](m.Empty()))
|
return F.Constant1[A](Make[E, A](m.Empty()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func MonadMap[E, A, B any](fa Const[E, A], f func(A) B) Const[E, B] {
|
func MonadMap[E, A, B any](fa Const[E, A], _ func(A) B) Const[E, B] {
|
||||||
return Make[E, B](fa.value)
|
return Make[E, B](fa.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ func Requester(builder *R.Builder) RIOEH.Requester {
|
|||||||
return F.Pipe5(
|
return F.Pipe5(
|
||||||
builder.GetBody(),
|
builder.GetBody(),
|
||||||
O.Fold(LZ.Of(E.Of[error](withoutBody)), E.Map[error](withBody)),
|
O.Fold(LZ.Of(E.Of[error](withoutBody)), E.Map[error](withBody)),
|
||||||
E.Ap[func(string) RIOE.ReaderIOEither[*http.Request]](builder.GetTargetUrl()),
|
E.Ap[func(string) RIOE.ReaderIOEither[*http.Request]](builder.GetTargetURL()),
|
||||||
E.Flap[error, RIOE.ReaderIOEither[*http.Request]](builder.GetMethod()),
|
E.Flap[error, RIOE.ReaderIOEither[*http.Request]](builder.GetMethod()),
|
||||||
E.GetOrElse(RIOE.Left[*http.Request]),
|
E.GetOrElse(RIOE.Left[*http.Request]),
|
||||||
RIOE.Map(func(req *http.Request) *http.Request {
|
RIOE.Map(func(req *http.Request) *http.Request {
|
||||||
|
|||||||
@@ -103,12 +103,19 @@ func ReadText(client Client) func(Requester) RIOE.ReaderIOEither[string] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReadJson sends a request, reads the response and parses the response as JSON
|
// ReadJson sends a request, reads the response and parses the response as JSON
|
||||||
|
//
|
||||||
|
// Deprecated: use [ReadJSON] instead
|
||||||
func ReadJson[A any](client Client) func(Requester) RIOE.ReaderIOEither[A] {
|
func ReadJson[A any](client Client) func(Requester) RIOE.ReaderIOEither[A] {
|
||||||
|
return ReadJSON[A](client)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadJSON sends a request, reads the response and parses the response as JSON
|
||||||
|
func ReadJSON[A any](client Client) func(Requester) RIOE.ReaderIOEither[A] {
|
||||||
return F.Flow3(
|
return F.Flow3(
|
||||||
ReadFullResponse(client),
|
ReadFullResponse(client),
|
||||||
RIOE.ChainFirstEitherK(F.Flow2(
|
RIOE.ChainFirstEitherK(F.Flow2(
|
||||||
H.Response,
|
H.Response,
|
||||||
H.ValidateJsonResponse,
|
H.ValidateJSONResponse,
|
||||||
)),
|
)),
|
||||||
RIOE.ChainEitherK(F.Flow2(
|
RIOE.ChainEitherK(F.Flow2(
|
||||||
H.Body,
|
H.Body,
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ func TestSendSingleRequest(t *testing.T) {
|
|||||||
|
|
||||||
req1 := MakeGetRequest("https://jsonplaceholder.typicode.com/posts/1")
|
req1 := MakeGetRequest("https://jsonplaceholder.typicode.com/posts/1")
|
||||||
|
|
||||||
readItem := ReadJson[PostItem](client)
|
readItem := ReadJSON[PostItem](client)
|
||||||
|
|
||||||
resp1 := readItem(req1)
|
resp1 := readItem(req1)
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ func TestSendSingleRequestWithHeaderUnsafe(t *testing.T) {
|
|||||||
R.Map(setHeaderUnsafe("Content-Type", "text/html")),
|
R.Map(setHeaderUnsafe("Content-Type", "text/html")),
|
||||||
)
|
)
|
||||||
|
|
||||||
readItem := ReadJson[PostItem](client)
|
readItem := ReadJSON[PostItem](client)
|
||||||
|
|
||||||
resp1 := F.Pipe2(
|
resp1 := F.Pipe2(
|
||||||
req1,
|
req1,
|
||||||
@@ -140,7 +140,7 @@ func TestSendSingleRequestWithHeaderSafe(t *testing.T) {
|
|||||||
WithHeader("Content-Type", "text/html").
|
WithHeader("Content-Type", "text/html").
|
||||||
Build()
|
Build()
|
||||||
|
|
||||||
readItem := ReadJson[PostItem](client)
|
readItem := ReadJSON[PostItem](client)
|
||||||
|
|
||||||
response := F.Pipe2(
|
response := F.Pipe2(
|
||||||
request,
|
request,
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ func MakeInjector(providers []Provider) InjectableFactory {
|
|||||||
var resolved sync.Map
|
var resolved sync.Map
|
||||||
|
|
||||||
// provide a mapping for all providers
|
// provide a mapping for all providers
|
||||||
factoryById := assembleProviders(providers)
|
factoryByID := assembleProviders(providers)
|
||||||
|
|
||||||
// the actual factory, we need lazy initialization
|
// the actual factory, we need lazy initialization
|
||||||
var injFct InjectableFactory
|
var injFct InjectableFactory
|
||||||
@@ -149,7 +149,7 @@ func MakeInjector(providers []Provider) InjectableFactory {
|
|||||||
T.Map2(F.Flow3(
|
T.Map2(F.Flow3(
|
||||||
Dependency.Id,
|
Dependency.Id,
|
||||||
R.Lookup[ProviderFactory, string],
|
R.Lookup[ProviderFactory, string],
|
||||||
I.Ap[O.Option[ProviderFactory]](factoryById),
|
I.Ap[O.Option[ProviderFactory]](factoryByID),
|
||||||
), handleMissingProvider),
|
), handleMissingProvider),
|
||||||
T.Tupled2(O.MonadGetOrElse[ProviderFactory]),
|
T.Tupled2(O.MonadGetOrElse[ProviderFactory]),
|
||||||
IG.Ap[ProviderFactory](injFct),
|
IG.Ap[ProviderFactory](injFct),
|
||||||
|
|||||||
10
di/token.go
10
di/token.go
@@ -65,15 +65,15 @@ type MultiInjectionToken[T any] interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// makeID creates a generator of unique string IDs
|
// makeID creates a generator of unique string IDs
|
||||||
func makeId() IO.IO[string] {
|
func makeID() IO.IO[string] {
|
||||||
var count atomic.Int64
|
var count atomic.Int64
|
||||||
return IO.MakeIO(func() string {
|
return IO.MakeIO(func() string {
|
||||||
return strconv.FormatInt(count.Add(1), 16)
|
return strconv.FormatInt(count.Add(1), 16)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// genId is the common generator of unique string IDs
|
// genID is the common generator of unique string IDs
|
||||||
var genId = makeId()
|
var genID = makeID()
|
||||||
|
|
||||||
type tokenBase struct {
|
type tokenBase struct {
|
||||||
name string
|
name string
|
||||||
@@ -156,7 +156,7 @@ func (m *multiInjectionToken[T]) Item() InjectionToken[T] {
|
|||||||
|
|
||||||
// makeToken create a unique [InjectionToken] for a specific type
|
// makeToken create a unique [InjectionToken] for a specific type
|
||||||
func makeInjectionToken[T any](name string, providerFactory O.Option[DIE.ProviderFactory]) InjectionToken[T] {
|
func makeInjectionToken[T any](name string, providerFactory O.Option[DIE.ProviderFactory]) InjectionToken[T] {
|
||||||
id := genId()
|
id := genID()
|
||||||
toIdentity := toType[T]()
|
toIdentity := toType[T]()
|
||||||
return &injectionToken[T]{
|
return &injectionToken[T]{
|
||||||
token[T]{makeTokenBase(name, id, DIE.Identity, providerFactory), toIdentity},
|
token[T]{makeTokenBase(name, id, DIE.Identity, providerFactory), toIdentity},
|
||||||
@@ -178,7 +178,7 @@ func MakeTokenWithDefault[T any](name string, providerFactory DIE.ProviderFactor
|
|||||||
|
|
||||||
// MakeMultiToken creates a [MultiInjectionToken]
|
// MakeMultiToken creates a [MultiInjectionToken]
|
||||||
func MakeMultiToken[T any](name string) MultiInjectionToken[T] {
|
func MakeMultiToken[T any](name string) MultiInjectionToken[T] {
|
||||||
id := genId()
|
id := genID()
|
||||||
toItem := toType[T]()
|
toItem := toType[T]()
|
||||||
toContainer := toArrayType(toItem)
|
toContainer := toArrayType(toItem)
|
||||||
containerName := fmt.Sprintf("Container[%s]", name)
|
containerName := fmt.Sprintf("Container[%s]", name)
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ func MonadChainFirst[E, A, B any](ma Either[E, A], f func(a A) Either[E, B]) Eit
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func MonadChainTo[A, E, B any](ma Either[E, A], mb Either[E, B]) Either[E, B] {
|
func MonadChainTo[A, E, B any](_ Either[E, A], mb Either[E, B]) Either[E, B] {
|
||||||
return mb
|
return mb
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
4
eq/eq.go
4
eq/eq.go
@@ -27,8 +27,8 @@ type eq[T any] struct {
|
|||||||
c func(x, y T) bool
|
c func(x, y T) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self eq[T]) Equals(x, y T) bool {
|
func (e eq[T]) Equals(x, y T) bool {
|
||||||
return self.c(x, y)
|
return e.c(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
func strictEq[A comparable](a, b A) bool {
|
func strictEq[A comparable](a, b A) bool {
|
||||||
|
|||||||
@@ -56,7 +56,11 @@ var (
|
|||||||
Monoid = ENDO.Monoid[*Builder]()
|
Monoid = ENDO.Monoid[*Builder]()
|
||||||
|
|
||||||
// Url is a [L.Lens] for the URL
|
// Url is a [L.Lens] for the URL
|
||||||
Url = L.MakeLensRef((*Builder).GetUrl, (*Builder).SetUrl)
|
//
|
||||||
|
// Deprecated: use [URL] instead
|
||||||
|
Url = L.MakeLensRef((*Builder).GetURL, (*Builder).SetURL)
|
||||||
|
// URL is a [L.Lens] for the URL
|
||||||
|
URL = L.MakeLensRef((*Builder).GetURL, (*Builder).SetURL)
|
||||||
// Method is a [L.Lens] for the HTTP method
|
// Method is a [L.Lens] for the HTTP method
|
||||||
Method = L.MakeLensRef((*Builder).GetMethod, (*Builder).SetMethod)
|
Method = L.MakeLensRef((*Builder).GetMethod, (*Builder).SetMethod)
|
||||||
// Body is a [L.Lens] for the request body
|
// Body is a [L.Lens] for the request body
|
||||||
@@ -83,8 +87,12 @@ var (
|
|||||||
WithQuery = Query.Set
|
WithQuery = Query.Set
|
||||||
// WithMethod creates a [Endomorphism] for a certain method
|
// WithMethod creates a [Endomorphism] for a certain method
|
||||||
WithMethod = Method.Set
|
WithMethod = Method.Set
|
||||||
// WithUrl creates a [Endomorphism] for a certain method
|
// WithUrl creates a [Endomorphism] for the URL
|
||||||
WithUrl = Url.Set
|
//
|
||||||
|
// Deprecated: use [WithURL] instead
|
||||||
|
WithUrl = URL.Set
|
||||||
|
// WithURL creates a [Endomorphism] for the URL
|
||||||
|
WithURL = URL.Set
|
||||||
// WithHeaders creates a [Endomorphism] for a set of headers
|
// WithHeaders creates a [Endomorphism] for a set of headers
|
||||||
WithHeaders = Headers.Set
|
WithHeaders = Headers.Set
|
||||||
// WithBody creates a [Endomorphism] for a request body
|
// WithBody creates a [Endomorphism] for a request body
|
||||||
@@ -148,7 +156,14 @@ func (builder *Builder) clone() *Builder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetTargetUrl constructs a full URL with query parameters on top of the provided URL string
|
// GetTargetUrl constructs a full URL with query parameters on top of the provided URL string
|
||||||
|
//
|
||||||
|
// Deprecated: use [GetTargetURL] instead
|
||||||
func (builder *Builder) GetTargetUrl() E.Either[error, string] {
|
func (builder *Builder) GetTargetUrl() E.Either[error, string] {
|
||||||
|
return builder.GetTargetURL()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTargetURL constructs a full URL with query parameters on top of the provided URL string
|
||||||
|
func (builder *Builder) GetTargetURL() E.Either[error, string] {
|
||||||
// construct the final URL
|
// construct the final URL
|
||||||
return F.Pipe3(
|
return F.Pipe3(
|
||||||
builder,
|
builder,
|
||||||
@@ -176,10 +191,15 @@ func (builder *Builder) GetTargetUrl() E.Either[error, string] {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use [GetURL] instead
|
||||||
func (builder *Builder) GetUrl() string {
|
func (builder *Builder) GetUrl() string {
|
||||||
return builder.url
|
return builder.url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (builder *Builder) GetURL() string {
|
||||||
|
return builder.url
|
||||||
|
}
|
||||||
|
|
||||||
func (builder *Builder) GetMethod() string {
|
func (builder *Builder) GetMethod() string {
|
||||||
return F.Pipe1(
|
return F.Pipe1(
|
||||||
builder.method,
|
builder.method,
|
||||||
@@ -209,11 +229,17 @@ func (builder *Builder) SetMethod(method string) *Builder {
|
|||||||
return builder
|
return builder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: use [SetURL] instead
|
||||||
func (builder *Builder) SetUrl(url string) *Builder {
|
func (builder *Builder) SetUrl(url string) *Builder {
|
||||||
builder.url = url
|
builder.url = url
|
||||||
return builder
|
return builder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (builder *Builder) SetURL(url string) *Builder {
|
||||||
|
builder.url = url
|
||||||
|
return builder
|
||||||
|
}
|
||||||
|
|
||||||
func (builder *Builder) SetHeaders(headers http.Header) *Builder {
|
func (builder *Builder) SetHeaders(headers http.Header) *Builder {
|
||||||
builder.headers = headers
|
builder.headers = headers
|
||||||
return builder
|
return builder
|
||||||
@@ -278,14 +304,21 @@ func WithoutHeader(name string) Endomorphism {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WithJson creates a [Endomorphism] to send JSON payload
|
// WithJson creates a [Endomorphism] to send JSON payload
|
||||||
|
//
|
||||||
|
// Deprecated: use [WithJSON] instead
|
||||||
func WithJson[T any](data T) Endomorphism {
|
func WithJson[T any](data T) Endomorphism {
|
||||||
|
return WithJSON[T](data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithJSON creates a [Endomorphism] to send JSON payload
|
||||||
|
func WithJSON[T any](data T) Endomorphism {
|
||||||
return Monoid.Concat(
|
return Monoid.Concat(
|
||||||
F.Pipe2(
|
F.Pipe2(
|
||||||
data,
|
data,
|
||||||
J.Marshal[T],
|
J.Marshal[T],
|
||||||
WithBody,
|
WithBody,
|
||||||
),
|
),
|
||||||
WithContentType(C.Json),
|
WithContentType(C.JSON),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ func TestBuilder(t *testing.T) {
|
|||||||
|
|
||||||
b1 := F.Pipe1(
|
b1 := F.Pipe1(
|
||||||
Default,
|
Default,
|
||||||
withContentType(C.Json),
|
withContentType(C.JSON),
|
||||||
)
|
)
|
||||||
|
|
||||||
b2 := F.Pipe1(
|
b2 := F.Pipe1(
|
||||||
@@ -48,7 +48,7 @@ func TestBuilder(t *testing.T) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert.Equal(t, O.None[string](), Default.GetHeader(name))
|
assert.Equal(t, O.None[string](), Default.GetHeader(name))
|
||||||
assert.Equal(t, O.Of(C.Json), b1.GetHeader(name))
|
assert.Equal(t, O.Of(C.JSON), b1.GetHeader(name))
|
||||||
assert.Equal(t, O.Of(C.TextPlain), b2.GetHeader(name))
|
assert.Equal(t, O.Of(C.TextPlain), b2.GetHeader(name))
|
||||||
assert.Equal(t, O.None[string](), b3.GetHeader(name))
|
assert.Equal(t, O.None[string](), b3.GetHeader(name))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ package content
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
TextPlain = "text/plain"
|
TextPlain = "text/plain"
|
||||||
Json = "application/json"
|
JSON = "application/json"
|
||||||
|
Json = JSON // Deprecated: use [JSON] instead
|
||||||
FormEncoded = "application/x-www-form-urlencoded"
|
FormEncoded = "application/x-www-form-urlencoded"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -45,29 +45,33 @@ type (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
// mime type to check if a media type matches
|
// mime type to check if a media type matches
|
||||||
reJsonMimeType = regexp.MustCompile(`application/(?:\w+\+)?json`)
|
reJSONMimeType = regexp.MustCompile(`application/(?:\w+\+)?json`)
|
||||||
// ValidateResponse validates an HTTP response and returns an [E.Either] if the response is not a success
|
// ValidateResponse validates an HTTP response and returns an [E.Either] if the response is not a success
|
||||||
ValidateResponse = E.FromPredicate(isValidStatus, StatusCodeError)
|
ValidateResponse = E.FromPredicate(isValidStatus, StatusCodeError)
|
||||||
// alidateJsonContentTypeString parses a content type a validates that it is valid JSON
|
// alidateJsonContentTypeString parses a content type a validates that it is valid JSON
|
||||||
validateJsonContentTypeString = F.Flow2(
|
validateJSONContentTypeString = F.Flow2(
|
||||||
ParseMediaType,
|
ParseMediaType,
|
||||||
E.ChainFirst(F.Flow2(
|
E.ChainFirst(F.Flow2(
|
||||||
T.First[string, map[string]string],
|
T.First[string, map[string]string],
|
||||||
E.FromPredicate(reJsonMimeType.MatchString, func(mimeType string) error {
|
E.FromPredicate(reJSONMimeType.MatchString, func(mimeType string) error {
|
||||||
return fmt.Errorf("mimetype [%s] is not a valid JSON content type", mimeType)
|
return fmt.Errorf("mimetype [%s] is not a valid JSON content type", mimeType)
|
||||||
}),
|
}),
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
// ValidateJsonResponse checks if an HTTP response is a valid JSON response
|
// ValidateJSONResponse checks if an HTTP response is a valid JSON response
|
||||||
ValidateJsonResponse = F.Flow2(
|
ValidateJSONResponse = F.Flow2(
|
||||||
E.Of[error, *H.Response],
|
E.Of[error, *H.Response],
|
||||||
E.ChainFirst(F.Flow5(
|
E.ChainFirst(F.Flow5(
|
||||||
GetHeader,
|
GetHeader,
|
||||||
R.Lookup[H.Header](HeaderContentType),
|
R.Lookup[H.Header](HeaderContentType),
|
||||||
O.Chain(A.First[string]),
|
O.Chain(A.First[string]),
|
||||||
E.FromOption[string](errors.OnNone("unable to access the [%s] header", HeaderContentType)),
|
E.FromOption[string](errors.OnNone("unable to access the [%s] header", HeaderContentType)),
|
||||||
E.ChainFirst(validateJsonContentTypeString),
|
E.ChainFirst(validateJSONContentTypeString),
|
||||||
)))
|
)))
|
||||||
|
// ValidateJsonResponse checks if an HTTP response is a valid JSON response
|
||||||
|
//
|
||||||
|
// Deprecated: use [ValidateJSONResponse] instead
|
||||||
|
ValidateJsonResponse = ValidateJSONResponse
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ func Error[A any](t *testing.T) func(E.Either[error, A]) bool {
|
|||||||
func TestValidateJsonContentTypeString(t *testing.T) {
|
func TestValidateJsonContentTypeString(t *testing.T) {
|
||||||
|
|
||||||
res := F.Pipe1(
|
res := F.Pipe1(
|
||||||
validateJsonContentTypeString(C.Json),
|
validateJSONContentTypeString(C.JSON),
|
||||||
NoError[ParsedMediaType](t),
|
NoError[ParsedMediaType](t),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ func TestValidateJsonContentTypeString(t *testing.T) {
|
|||||||
func TestValidateInvalidJsonContentTypeString(t *testing.T) {
|
func TestValidateInvalidJsonContentTypeString(t *testing.T) {
|
||||||
|
|
||||||
res := F.Pipe1(
|
res := F.Pipe1(
|
||||||
validateJsonContentTypeString("application/xml"),
|
validateJSONContentTypeString("application/xml"),
|
||||||
Error[ParsedMediaType](t),
|
Error[ParsedMediaType](t),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ func AssertIdentity[HKTA, HKTAA, A any](t *testing.T,
|
|||||||
|
|
||||||
fap func(HKTAA, HKTA) HKTA,
|
fap func(HKTAA, HKTA) HKTA,
|
||||||
) func(fa HKTA) bool {
|
) func(fa HKTA) bool {
|
||||||
|
// mark as test helper
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
return func(fa HKTA) bool {
|
return func(fa HKTA) bool {
|
||||||
|
|
||||||
left := fap(fof(F.Identity[A]), fa)
|
left := fap(fof(F.Identity[A]), fa)
|
||||||
@@ -57,6 +60,9 @@ func AssertHomomorphism[HKTA, HKTB, HKTAB, A, B any](t *testing.T,
|
|||||||
|
|
||||||
ab func(A) B,
|
ab func(A) B,
|
||||||
) func(a A) bool {
|
) func(a A) bool {
|
||||||
|
// mark as test helper
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
return func(a A) bool {
|
return func(a A) bool {
|
||||||
|
|
||||||
left := fap(fofab(ab), fofa(a))
|
left := fap(fofab(ab), fofa(a))
|
||||||
@@ -73,7 +79,6 @@ func AssertInterchange[HKTA, HKTB, HKTAB, HKTABB, A, B any](t *testing.T,
|
|||||||
eq E.Eq[HKTB],
|
eq E.Eq[HKTB],
|
||||||
|
|
||||||
fofa func(A) HKTA,
|
fofa func(A) HKTA,
|
||||||
fofb func(B) HKTB,
|
|
||||||
fofab func(func(A) B) HKTAB,
|
fofab func(func(A) B) HKTAB,
|
||||||
fofabb func(func(func(A) B) B) HKTABB,
|
fofabb func(func(func(A) B) B) HKTABB,
|
||||||
|
|
||||||
@@ -82,6 +87,9 @@ func AssertInterchange[HKTA, HKTB, HKTAB, HKTABB, A, B any](t *testing.T,
|
|||||||
|
|
||||||
ab func(A) B,
|
ab func(A) B,
|
||||||
) func(a A) bool {
|
) func(a A) bool {
|
||||||
|
// mark as test helper
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
return func(a A) bool {
|
return func(a A) bool {
|
||||||
|
|
||||||
fab := fofab(ab)
|
fab := fofab(ab)
|
||||||
@@ -127,12 +135,15 @@ func AssertLaws[HKTA, HKTB, HKTC, HKTAA, HKTAB, HKTBC, HKTAC, HKTABB, HKTABAC, A
|
|||||||
ab func(A) B,
|
ab func(A) B,
|
||||||
bc func(B) C,
|
bc func(B) C,
|
||||||
) func(a A) bool {
|
) func(a A) bool {
|
||||||
|
// mark as test helper
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
// apply laws
|
// apply laws
|
||||||
apply := L.AssertLaws(t, eqa, eqc, fofab, fofbc, faa, fab, fac, fbc, fmap, fapab, fapbc, fapac, fapabac, ab, bc)
|
apply := L.AssertLaws(t, eqa, eqc, fofab, fofbc, faa, fab, fac, fbc, fmap, fapab, fapbc, fapac, fapabac, ab, bc)
|
||||||
// applicative laws
|
// applicative laws
|
||||||
identity := AssertIdentity(t, eqa, fofaa, fapaa)
|
identity := AssertIdentity(t, eqa, fofaa, fapaa)
|
||||||
homomorphism := AssertHomomorphism(t, eqb, fofa, fofb, fofab, fapab, ab)
|
homomorphism := AssertHomomorphism(t, eqb, fofa, fofb, fofab, fapab, ab)
|
||||||
interchange := AssertInterchange(t, eqb, fofa, fofb, fofab, fofabb, fapab, fapabb, ab)
|
interchange := AssertInterchange(t, eqb, fofa, fofab, fofabb, fapab, fapabb, ab)
|
||||||
|
|
||||||
return func(a A) bool {
|
return func(a A) bool {
|
||||||
fa := fofa(a)
|
fa := fofa(a)
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ func AssertAssociativeComposition[HKTA, HKTB, HKTC, HKTAB, HKTBC, HKTAC, HKTABAC
|
|||||||
ab func(A) B,
|
ab func(A) B,
|
||||||
bc func(B) C,
|
bc func(B) C,
|
||||||
) func(fa HKTA) bool {
|
) func(fa HKTA) bool {
|
||||||
|
t.Helper()
|
||||||
return func(fa HKTA) bool {
|
return func(fa HKTA) bool {
|
||||||
|
|
||||||
fab := fofab(ab)
|
fab := fofab(ab)
|
||||||
@@ -86,6 +87,8 @@ func AssertLaws[HKTA, HKTB, HKTC, HKTAB, HKTBC, HKTAC, HKTABAC, A, B, C any](t *
|
|||||||
ab func(A) B,
|
ab func(A) B,
|
||||||
bc func(B) C,
|
bc func(B) C,
|
||||||
) func(fa HKTA) bool {
|
) func(fa HKTA) bool {
|
||||||
|
// mark as test helper
|
||||||
|
t.Helper()
|
||||||
// functor laws
|
// functor laws
|
||||||
functor := FCT.AssertLaws(t, eqa, eqc, faa, fab, fac, fbc, ab, bc)
|
functor := FCT.AssertLaws(t, eqa, eqc, faa, fab, fac, fbc, ab, bc)
|
||||||
// associative composition laws
|
// associative composition laws
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ import (
|
|||||||
func AssertAssociativity[HKTA, HKTB, HKTC, A, B, C any](t *testing.T,
|
func AssertAssociativity[HKTA, HKTB, HKTC, A, B, C any](t *testing.T,
|
||||||
eq E.Eq[HKTC],
|
eq E.Eq[HKTC],
|
||||||
|
|
||||||
fofa func(A) HKTA,
|
|
||||||
fofb func(B) HKTB,
|
fofb func(B) HKTB,
|
||||||
fofc func(C) HKTC,
|
fofc func(C) HKTC,
|
||||||
|
|
||||||
@@ -61,7 +60,6 @@ func AssertLaws[HKTA, HKTB, HKTC, HKTAB, HKTBC, HKTAC, HKTABAC, A, B, C any](t *
|
|||||||
eqa E.Eq[HKTA],
|
eqa E.Eq[HKTA],
|
||||||
eqc E.Eq[HKTC],
|
eqc E.Eq[HKTC],
|
||||||
|
|
||||||
fofa func(A) HKTA,
|
|
||||||
fofb func(B) HKTB,
|
fofb func(B) HKTB,
|
||||||
fofc func(C) HKTC,
|
fofc func(C) HKTC,
|
||||||
|
|
||||||
@@ -91,7 +89,7 @@ func AssertLaws[HKTA, HKTB, HKTC, HKTAB, HKTBC, HKTAC, HKTABAC, A, B, C any](t *
|
|||||||
// apply laws
|
// apply laws
|
||||||
apply := L.AssertLaws(t, eqa, eqc, fofab, fofbc, faa, fab, fac, fbc, fmap, fapab, fapbc, fapac, fapabac, ab, bc)
|
apply := L.AssertLaws(t, eqa, eqc, fofab, fofbc, faa, fab, fac, fbc, fmap, fapab, fapbc, fapac, fapabac, ab, bc)
|
||||||
// chain laws
|
// chain laws
|
||||||
associativity := AssertAssociativity(t, eqc, fofa, fofb, fofc, chainab, chainac, chainbc, ab, bc)
|
associativity := AssertAssociativity(t, eqc, fofb, fofc, chainab, chainac, chainbc, ab, bc)
|
||||||
|
|
||||||
return func(fa HKTA) bool {
|
return func(fa HKTA) bool {
|
||||||
return apply(fa) && associativity(fa)
|
return apply(fa) && associativity(fa)
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import (
|
|||||||
//
|
//
|
||||||
// F.map(fa, a => a) <-> fa
|
// F.map(fa, a => a) <-> fa
|
||||||
func AssertIdentity[HKTA, A any](t *testing.T, eq E.Eq[HKTA], fmap func(HKTA, func(A) A) HKTA) func(fa HKTA) bool {
|
func AssertIdentity[HKTA, A any](t *testing.T, eq E.Eq[HKTA], fmap func(HKTA, func(A) A) HKTA) func(fa HKTA) bool {
|
||||||
|
t.Helper()
|
||||||
return func(fa HKTA) bool {
|
return func(fa HKTA) bool {
|
||||||
return assert.True(t, eq.Equals(fa, fmap(fa, F.Identity[A])), "Functor identity law")
|
return assert.True(t, eq.Equals(fa, fmap(fa, F.Identity[A])), "Functor identity law")
|
||||||
}
|
}
|
||||||
@@ -46,6 +47,7 @@ func AssertComposition[HKTA, HKTB, HKTC, A, B, C any](
|
|||||||
ab func(A) B,
|
ab func(A) B,
|
||||||
bc func(B) C,
|
bc func(B) C,
|
||||||
) func(fa HKTA) bool {
|
) func(fa HKTA) bool {
|
||||||
|
t.Helper()
|
||||||
return func(fa HKTA) bool {
|
return func(fa HKTA) bool {
|
||||||
return assert.True(t, eq.Equals(fac(fa, F.Flow2(ab, bc)), fbc(fab(fa, ab), bc)), "Functor composition law")
|
return assert.True(t, eq.Equals(fac(fa, F.Flow2(ab, bc)), fbc(fab(fa, ab), bc)), "Functor composition law")
|
||||||
}
|
}
|
||||||
@@ -63,6 +65,7 @@ func AssertLaws[HKTA, HKTB, HKTC, A, B, C any](t *testing.T,
|
|||||||
ab func(A) B,
|
ab func(A) B,
|
||||||
bc func(B) C,
|
bc func(B) C,
|
||||||
) func(fa HKTA) bool {
|
) func(fa HKTA) bool {
|
||||||
|
t.Helper()
|
||||||
identity := AssertIdentity(t, eqa, faa)
|
identity := AssertIdentity(t, eqa, faa)
|
||||||
composition := AssertComposition(t, eqc, fab, fac, fbc, ab, bc)
|
composition := AssertComposition(t, eqc, fab, fac, fbc, ab, bc)
|
||||||
|
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ func AssertLaws[HKTA, HKTB, HKTC, HKTAA, HKTAB, HKTBC, HKTAC, HKTABB, HKTABAC, A
|
|||||||
// applicative laws
|
// applicative laws
|
||||||
applicative := LA.AssertLaws(t, eqa, eqb, eqc, fofa, fofb, fofaa, fofab, fofbc, fofabb, faa, fab, fac, fbc, fmap, fapaa, fapab, fapbc, fapac, fapabb, fapabac, ab, bc)
|
applicative := LA.AssertLaws(t, eqa, eqb, eqc, fofa, fofb, fofaa, fofab, fofbc, fofabb, faa, fab, fac, fbc, fmap, fapaa, fapab, fapbc, fapac, fapabb, fapabac, ab, bc)
|
||||||
// chain laws
|
// chain laws
|
||||||
chain := LC.AssertLaws(t, eqa, eqc, fofa, fofb, fofc, fofab, fofbc, faa, fab, fac, fbc, fmap, chainab, chainac, chainbc, fapab, fapbc, fapac, fapabac, ab, bc)
|
chain := LC.AssertLaws(t, eqa, eqc, fofb, fofc, fofab, fofbc, faa, fab, fac, fbc, fmap, chainab, chainac, chainbc, fapab, fapbc, fapac, fapabac, ab, bc)
|
||||||
// monad laws
|
// monad laws
|
||||||
leftIdentity := AssertLeftIdentity(t, eqb, fofa, fofb, chainab, ab)
|
leftIdentity := AssertLeftIdentity(t, eqb, fofa, fofb, chainab, ab)
|
||||||
rightIdentity := AssertRightIdentity(t, eqa, fofa, chainaa)
|
rightIdentity := AssertRightIdentity(t, eqa, fofa, chainaa)
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ import (
|
|||||||
F "github.com/IBM/fp-go/function"
|
F "github.com/IBM/fp-go/function"
|
||||||
)
|
)
|
||||||
|
|
||||||
// LogJson converts the argument to JSON and then logs it via the format string
|
// LogJSON converts the argument to JSON and then logs it via the format string
|
||||||
// Can be used with [ChainFirst]
|
// Can be used with [ChainFirst]
|
||||||
func LogJson[GA ~func() ET.Either[error, any], A any](prefix string) func(A) GA {
|
func LogJSON[GA ~func() ET.Either[error, any], A any](prefix string) func(A) GA {
|
||||||
return func(a A) GA {
|
return func(a A) GA {
|
||||||
// log this
|
// log this
|
||||||
return F.Pipe3(
|
return F.Pipe3(
|
||||||
@@ -41,3 +41,11 @@ func LogJson[GA ~func() ET.Either[error, any], A any](prefix string) func(A) GA
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LogJson converts the argument to JSON and then logs it via the format string
|
||||||
|
// Can be used with [ChainFirst]
|
||||||
|
//
|
||||||
|
// Deprecated: use [LogJSON] instead
|
||||||
|
func LogJson[GA ~func() ET.Either[error, any], A any](prefix string) func(A) GA {
|
||||||
|
return LogJSON[GA, A](prefix)
|
||||||
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ func Requester(builder *R.Builder) IOEH.Requester {
|
|||||||
return F.Pipe5(
|
return F.Pipe5(
|
||||||
builder.GetBody(),
|
builder.GetBody(),
|
||||||
O.Fold(LZ.Of(E.Of[error](withoutBody)), E.Map[error](withBody)),
|
O.Fold(LZ.Of(E.Of[error](withoutBody)), E.Map[error](withBody)),
|
||||||
E.Ap[func(string) IOE.IOEither[error, *http.Request]](builder.GetTargetUrl()),
|
E.Ap[func(string) IOE.IOEither[error, *http.Request]](builder.GetTargetURL()),
|
||||||
E.Flap[error, IOE.IOEither[error, *http.Request]](builder.GetMethod()),
|
E.Flap[error, IOE.IOEither[error, *http.Request]](builder.GetMethod()),
|
||||||
E.GetOrElse(IOE.Left[*http.Request, error]),
|
E.GetOrElse(IOE.Left[*http.Request, error]),
|
||||||
IOE.Map[error](func(req *http.Request) *http.Request {
|
IOE.Map[error](func(req *http.Request) *http.Request {
|
||||||
|
|||||||
@@ -118,12 +118,19 @@ func ReadText(client Client) func(Requester) IOE.IOEither[error, string] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReadJson sends a request, reads the response and parses the response as JSON
|
// ReadJson sends a request, reads the response and parses the response as JSON
|
||||||
|
//
|
||||||
|
// Deprecated: use [ReadJSON] instead
|
||||||
func ReadJson[A any](client Client) func(Requester) IOE.IOEither[error, A] {
|
func ReadJson[A any](client Client) func(Requester) IOE.IOEither[error, A] {
|
||||||
|
return ReadJSON[A](client)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadJSON sends a request, reads the response and parses the response as JSON
|
||||||
|
func ReadJSON[A any](client Client) func(Requester) IOE.IOEither[error, A] {
|
||||||
return F.Flow3(
|
return F.Flow3(
|
||||||
ReadFullResponse(client),
|
ReadFullResponse(client),
|
||||||
IOE.ChainFirstEitherK(F.Flow2(
|
IOE.ChainFirstEitherK(F.Flow2(
|
||||||
H.Response,
|
H.Response,
|
||||||
H.ValidateJsonResponse,
|
H.ValidateJSONResponse,
|
||||||
)),
|
)),
|
||||||
IOE.ChainEitherK(F.Flow2(
|
IOE.ChainEitherK(F.Flow2(
|
||||||
H.Body,
|
H.Body,
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ func TestRetryHttp(t *testing.T) {
|
|||||||
action := func(status R.RetryStatus) IOE.IOEither[error, *PostItem] {
|
action := func(status R.RetryStatus) IOE.IOEither[error, *PostItem] {
|
||||||
return F.Pipe1(
|
return F.Pipe1(
|
||||||
MakeGetRequest(urls[status.IterNumber]),
|
MakeGetRequest(urls[status.IterNumber]),
|
||||||
ReadJson[*PostItem](client),
|
ReadJSON[*PostItem](client),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,14 @@ import (
|
|||||||
|
|
||||||
// LogJson converts the argument to pretty printed JSON and then logs it via the format string
|
// LogJson converts the argument to pretty printed JSON and then logs it via the format string
|
||||||
// Can be used with [ChainFirst]
|
// Can be used with [ChainFirst]
|
||||||
|
//
|
||||||
|
// Deprecated: use [LogJSON] instead
|
||||||
func LogJson[A any](prefix string) func(A) IOEither[error, any] {
|
func LogJson[A any](prefix string) func(A) IOEither[error, any] {
|
||||||
return G.LogJson[IOEither[error, any], A](prefix)
|
return G.LogJson[IOEither[error, any], A](prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LogJSON converts the argument to pretty printed JSON and then logs it via the format string
|
||||||
|
// Can be used with [ChainFirst]
|
||||||
|
func LogJSON[A any](prefix string) func(A) IOEither[error, any] {
|
||||||
|
return G.LogJSON[IOEither[error, any], A](prefix)
|
||||||
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ func TestLogging(t *testing.T) {
|
|||||||
|
|
||||||
res := F.Pipe1(
|
res := F.Pipe1(
|
||||||
Of[error](src),
|
Of[error](src),
|
||||||
ChainFirst(LogJson[*SomeData]("Data: \n%s")),
|
ChainFirst(LogJSON[*SomeData]("Data: \n%s")),
|
||||||
)
|
)
|
||||||
|
|
||||||
dst := res()
|
dst := res()
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ type magma[A any] struct {
|
|||||||
c func(A, A) A
|
c func(A, A) A
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self magma[A]) Concat(x A, y A) A {
|
func (m magma[A]) Concat(x A, y A) A {
|
||||||
return self.c(x, y)
|
return m.c(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakeMagma[A any](c func(A, A) A) Magma[A] {
|
func MakeMagma[A any](c func(A, A) A) Magma[A] {
|
||||||
@@ -63,17 +63,17 @@ func FilterFirst[A any](p func(A) bool) func(Magma[A]) Magma[A] {
|
|||||||
func FilterSecond[A any](p func(A) bool) func(Magma[A]) Magma[A] {
|
func FilterSecond[A any](p func(A) bool) func(Magma[A]) Magma[A] {
|
||||||
return func(m Magma[A]) Magma[A] {
|
return func(m Magma[A]) Magma[A] {
|
||||||
c := m.Concat
|
c := m.Concat
|
||||||
return MakeMagma(func(x A, y A) A {
|
return MakeMagma(func(x, y A) A {
|
||||||
return filterSecond(p, c, x, y)
|
return filterSecond(p, c, x, y)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func first[A any](x A, y A) A {
|
func first[A any](x, _ A) A {
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
||||||
func second[A any](x A, y A) A {
|
func second[A any](_, y A) A {
|
||||||
return y
|
return y
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ func Second[A any]() Magma[A] {
|
|||||||
return MakeMagma(second[A])
|
return MakeMagma(second[A])
|
||||||
}
|
}
|
||||||
|
|
||||||
func endo[A any](f func(A) A, c func(A, A) A, x A, y A) A {
|
func endo[A any](f func(A) A, c func(A, A) A, x, y A) A {
|
||||||
return c(f(x), f(y))
|
return c(f(x), f(y))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// FunctionMonoid forms a monoid as long as you can provide a monoid for the codomain.
|
// FunctionMonoid forms a monoid as long as you can provide a monoid for the codomain.
|
||||||
func FunctionMonoid[A, B any](M Monoid[B]) Monoid[func(A) B] {
|
func FunctionMonoid[A, B any](m Monoid[B]) Monoid[func(A) B] {
|
||||||
return MakeMonoid(
|
return MakeMonoid(
|
||||||
S.FunctionSemigroup[A, B](M).Concat,
|
S.FunctionSemigroup[A, B](m).Concat,
|
||||||
F.Constant1[A](M.Empty()),
|
F.Constant1[A](m.Empty()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,12 +29,12 @@ type monoid[A any] struct {
|
|||||||
e A
|
e A
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self monoid[A]) Concat(x A, y A) A {
|
func (m monoid[A]) Concat(x, y A) A {
|
||||||
return self.c(x, y)
|
return m.c(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self monoid[A]) Empty() A {
|
func (m monoid[A]) Empty() A {
|
||||||
return self.e
|
return m.e
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeMonoid creates a monoid given a concat function and an empty element
|
// MakeMonoid creates a monoid given a concat function and an empty element
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ type (
|
|||||||
// modifying that copy
|
// modifying that copy
|
||||||
func setCopy[SET ~func(*S, A) *S, S, A any](setter SET) func(s *S, a A) *S {
|
func setCopy[SET ~func(*S, A) *S, S, A any](setter SET) func(s *S, a A) *S {
|
||||||
return func(s *S, a A) *S {
|
return func(s *S, a A) *S {
|
||||||
copy := *s
|
cpy := *s
|
||||||
return setter(©, a)
|
return setter(&cpy, a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,8 +45,8 @@ func setCopyCurried[SET ~func(A) EM.Endomorphism[*S], S, A any](setter SET) func
|
|||||||
return func(a A) EM.Endomorphism[*S] {
|
return func(a A) EM.Endomorphism[*S] {
|
||||||
seta := setter(a)
|
seta := setter(a)
|
||||||
return func(s *S) *S {
|
return func(s *S) *S {
|
||||||
copy := *s
|
cpy := *s
|
||||||
return seta(©)
|
return seta(&cpy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ func (inner *Inner) getA() int {
|
|||||||
return inner.A
|
return inner.A
|
||||||
}
|
}
|
||||||
|
|
||||||
func (inner *Inner) setA(A int) *Inner {
|
func (inner *Inner) setA(a int) *Inner {
|
||||||
inner.A = A
|
inner.A = a
|
||||||
return inner
|
return inner
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ type Optional[S, A any] struct {
|
|||||||
// modifying that copy
|
// modifying that copy
|
||||||
func setCopy[SET ~func(*S, A) *S, S, A any](setter SET) func(s *S, a A) *S {
|
func setCopy[SET ~func(*S, A) *S, S, A any](setter SET) func(s *S, a A) *S {
|
||||||
return func(s *S, a A) *S {
|
return func(s *S, a A) *S {
|
||||||
copy := *s
|
cpy := *s
|
||||||
return setter(©, a)
|
return setter(&cpy, a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ import (
|
|||||||
O "github.com/IBM/fp-go/option"
|
O "github.com/IBM/fp-go/option"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PrismAsOptional converts a prism into an optional
|
// AsOptional converts a prism into an optional
|
||||||
func PrismAsOptional[S, A any](sa P.Prism[S, A]) OPT.Optional[S, A] {
|
func AsOptional[S, A any](sa P.Prism[S, A]) OPT.Optional[S, A] {
|
||||||
return OPT.MakeOptional(
|
return OPT.MakeOptional(
|
||||||
sa.GetOption,
|
sa.GetOption,
|
||||||
func(s S, a A) S {
|
func(s S, a A) S {
|
||||||
@@ -38,5 +38,5 @@ func PrismSome[A any]() P.Prism[O.Option[A], A] {
|
|||||||
|
|
||||||
// Some returns a `Optional` from a `Optional` focused on the `Some` of a `Option` type.
|
// Some returns a `Optional` from a `Optional` focused on the `Some` of a `Option` type.
|
||||||
func Some[S, A any](soa OPT.Optional[S, O.Option[A]]) OPT.Optional[S, A] {
|
func Some[S, A any](soa OPT.Optional[S, O.Option[A]]) OPT.Optional[S, A] {
|
||||||
return OPT.Compose[S](PrismAsOptional(PrismSome[A]()))(soa)
|
return OPT.Compose[S](AsOptional(PrismSome[A]()))(soa)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ func Chain[A, B any](f func(A) Option[B]) func(Option[A]) Option[B] {
|
|||||||
return Fold(None[B], f)
|
return Fold(None[B], f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func MonadChainTo[A, B any](ma Option[A], mb Option[B]) Option[B] {
|
func MonadChainTo[A, B any](_ Option[A], mb Option[B]) Option[B] {
|
||||||
return mb
|
return mb
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,11 +42,11 @@ func Monoid[A any]() M.Monoid[Ord[A]] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MaxSemigroup returns a semigroup where `concat` will return the maximum, based on the provided order.
|
// MaxSemigroup returns a semigroup where `concat` will return the maximum, based on the provided order.
|
||||||
func MaxSemigroup[A any](O Ord[A]) S.Semigroup[A] {
|
func MaxSemigroup[A any](o Ord[A]) S.Semigroup[A] {
|
||||||
return S.MakeSemigroup(Max(O))
|
return S.MakeSemigroup(Max(o))
|
||||||
}
|
}
|
||||||
|
|
||||||
// MaxSemigroup returns a semigroup where `concat` will return the minimum, based on the provided order.
|
// MaxSemigroup returns a semigroup where `concat` will return the minimum, based on the provided order.
|
||||||
func MinSemigroup[A any](O Ord[A]) S.Semigroup[A] {
|
func MinSemigroup[A any](o Ord[A]) S.Semigroup[A] {
|
||||||
return S.MakeSemigroup(Min(O))
|
return S.MakeSemigroup(Min(o))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,10 +132,10 @@ func FromStrictCompare[A C.Ordered]() Ord[A] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Lt tests whether one value is strictly less than another
|
// Lt tests whether one value is strictly less than another
|
||||||
func Lt[A any](O Ord[A]) func(A) func(A) bool {
|
func Lt[A any](o Ord[A]) func(A) func(A) bool {
|
||||||
return func(second A) func(A) bool {
|
return func(second A) func(A) bool {
|
||||||
return func(first A) bool {
|
return func(first A) bool {
|
||||||
return O.Compare(first, second) < 0
|
return o.Compare(first, second) < 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// SemigroupAny combines predicates via ||
|
// SemigroupAny combines predicates via ||
|
||||||
func SemigroupAny[A any](predicate func(A) bool) S.Semigroup[func(A) bool] {
|
func SemigroupAny[A any]() S.Semigroup[func(A) bool] {
|
||||||
return S.MakeSemigroup(func(first func(A) bool, second func(A) bool) func(A) bool {
|
return S.MakeSemigroup(func(first func(A) bool, second func(A) bool) func(A) bool {
|
||||||
return F.Pipe1(
|
return F.Pipe1(
|
||||||
first,
|
first,
|
||||||
@@ -32,7 +32,7 @@ func SemigroupAny[A any](predicate func(A) bool) S.Semigroup[func(A) bool] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SemigroupAll combines predicates via &&
|
// SemigroupAll combines predicates via &&
|
||||||
func SemigroupAll[A any](predicate func(A) bool) S.Semigroup[func(A) bool] {
|
func SemigroupAll[A any]() S.Semigroup[func(A) bool] {
|
||||||
return S.MakeSemigroup(func(first func(A) bool, second func(A) bool) func(A) bool {
|
return S.MakeSemigroup(func(first func(A) bool, second func(A) bool) func(A) bool {
|
||||||
return F.Pipe1(
|
return F.Pipe1(
|
||||||
first,
|
first,
|
||||||
@@ -42,17 +42,17 @@ func SemigroupAll[A any](predicate func(A) bool) S.Semigroup[func(A) bool] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MonoidAny combines predicates via ||
|
// MonoidAny combines predicates via ||
|
||||||
func MonoidAny[A any](predicate func(A) bool) S.Semigroup[func(A) bool] {
|
func MonoidAny[A any]() S.Semigroup[func(A) bool] {
|
||||||
return M.MakeMonoid(
|
return M.MakeMonoid(
|
||||||
SemigroupAny(predicate).Concat,
|
SemigroupAny[A]().Concat,
|
||||||
F.Constant1[A](false),
|
F.Constant1[A](false),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MonoidAll combines predicates via &&
|
// MonoidAll combines predicates via &&
|
||||||
func MonoidAll[A any](predicate func(A) bool) S.Semigroup[func(A) bool] {
|
func MonoidAll[A any]() S.Semigroup[func(A) bool] {
|
||||||
return M.MakeMonoid(
|
return M.MakeMonoid(
|
||||||
SemigroupAll(predicate).Concat,
|
SemigroupAll[A]().Concat,
|
||||||
F.Constant1[A](true),
|
F.Constant1[A](true),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ const emptyDuration = time.Duration(0)
|
|||||||
|
|
||||||
var ordDuration = ord.FromStrictCompare[time.Duration]()
|
var ordDuration = ord.FromStrictCompare[time.Duration]()
|
||||||
|
|
||||||
// 'RetryPolicy' is a 'Monoid'. You can collapse multiple strategies into one using 'concat'.
|
// Monoid 'RetryPolicy' is a 'Monoid'. You can collapse multiple strategies into one using 'concat'.
|
||||||
// The semantics of this combination are as follows:
|
// The semantics of this combination are as follows:
|
||||||
//
|
//
|
||||||
// 1. If either policy returns 'None', the combined policy returns
|
// 1. If either policy returns 'None', the combined policy returns
|
||||||
@@ -98,10 +98,8 @@ func ExponentialBackoff(delay time.Duration) RetryPolicy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// DefaultRetryStatus is the default retry status. Exported mostly to allow user code
|
||||||
* Initial, default retry status. Exported mostly to allow user code
|
// to test their handlers and retry policies.
|
||||||
* to test their handlers and retry policies.
|
|
||||||
*/
|
|
||||||
var DefaultRetryStatus = RetryStatus{
|
var DefaultRetryStatus = RetryStatus{
|
||||||
IterNumber: 0,
|
IterNumber: 0,
|
||||||
CumulativeDelay: 0,
|
CumulativeDelay: 0,
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ func TestMultipleHttpRequests(t *testing.T) {
|
|||||||
// prepare the http client
|
// prepare the http client
|
||||||
client := H.MakeClient(HTTP.DefaultClient)
|
client := H.MakeClient(HTTP.DefaultClient)
|
||||||
// readSinglePost sends a GET request and parses the response as [PostItem]
|
// readSinglePost sends a GET request and parses the response as [PostItem]
|
||||||
readSinglePost := H.ReadJson[PostItem](client)
|
readSinglePost := H.ReadJSON[PostItem](client)
|
||||||
|
|
||||||
// total number of http requests
|
// total number of http requests
|
||||||
count := 10
|
count := 10
|
||||||
@@ -78,9 +78,9 @@ func heterogeneousHTTPRequests() R.ReaderIOEither[T.Tuple2[PostItem, CatFact]] {
|
|||||||
// prepare the http client
|
// prepare the http client
|
||||||
client := H.MakeClient(HTTP.DefaultClient)
|
client := H.MakeClient(HTTP.DefaultClient)
|
||||||
// readSinglePost sends a GET request and parses the response as [PostItem]
|
// readSinglePost sends a GET request and parses the response as [PostItem]
|
||||||
readSinglePost := H.ReadJson[PostItem](client)
|
readSinglePost := H.ReadJSON[PostItem](client)
|
||||||
// readSingleCatFact sends a GET request and parses the response as [CatFact]
|
// readSingleCatFact sends a GET request and parses the response as [CatFact]
|
||||||
readSingleCatFact := H.ReadJson[CatFact](client)
|
readSingleCatFact := H.ReadJSON[CatFact](client)
|
||||||
|
|
||||||
return F.Pipe3(
|
return F.Pipe3(
|
||||||
T.MakeTuple2("https://jsonplaceholder.typicode.com/posts/1", "https://catfact.ninja/fact"),
|
T.MakeTuple2("https://jsonplaceholder.typicode.com/posts/1", "https://catfact.ninja/fact"),
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ func Example_renderPage() {
|
|||||||
get := F.Flow4(
|
get := F.Flow4(
|
||||||
idxToURL,
|
idxToURL,
|
||||||
H.MakeGetRequest,
|
H.MakeGetRequest,
|
||||||
H.ReadJson[PostItem](client),
|
H.ReadJSON[PostItem](client),
|
||||||
R.Map(PostItem.getTitle),
|
R.Map(PostItem.getTitle),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ func heterogeneousHTTPRequests(count int) R.ReaderIOEither[[]T.Tuple2[PostItem,
|
|||||||
// prepare the http client
|
// prepare the http client
|
||||||
client := H.MakeClient(HTTP.DefaultClient)
|
client := H.MakeClient(HTTP.DefaultClient)
|
||||||
// readSinglePost sends a GET request and parses the response as [PostItem]
|
// readSinglePost sends a GET request and parses the response as [PostItem]
|
||||||
readSinglePost := H.ReadJson[PostItem](client)
|
readSinglePost := H.ReadJSON[PostItem](client)
|
||||||
// readSingleCatFact sends a GET request and parses the response as [CatFact]
|
// readSingleCatFact sends a GET request and parses the response as [CatFact]
|
||||||
readSingleCatFact := H.ReadJson[CatFact](client)
|
readSingleCatFact := H.ReadJSON[CatFact](client)
|
||||||
|
|
||||||
single := F.Pipe2(
|
single := F.Pipe2(
|
||||||
T.MakeTuple2("https://jsonplaceholder.typicode.com/posts/1", "https://catfact.ninja/fact"),
|
T.MakeTuple2("https://jsonplaceholder.typicode.com/posts/1", "https://catfact.ninja/fact"),
|
||||||
|
|||||||
@@ -42,10 +42,10 @@ func Reverse[A any](m Semigroup[A]) Semigroup[A] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FunctionSemigroup forms a semigroup as long as you can provide a semigroup for the codomain.
|
// FunctionSemigroup forms a semigroup as long as you can provide a semigroup for the codomain.
|
||||||
func FunctionSemigroup[A, B any](S Semigroup[B]) Semigroup[func(A) B] {
|
func FunctionSemigroup[A, B any](s Semigroup[B]) Semigroup[func(A) B] {
|
||||||
return MakeSemigroup(func(f func(A) B, g func(A) B) func(A) B {
|
return MakeSemigroup(func(f func(A) B, g func(A) B) func(A) B {
|
||||||
return func(a A) B {
|
return func(a A) B {
|
||||||
return S.Concat(f(a), g(a))
|
return s.Concat(f(a), g(a))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user