diff --git a/v2/http/types.go b/v2/http/types.go index 63206bf..5c61728 100644 --- a/v2/http/types.go +++ b/v2/http/types.go @@ -103,4 +103,7 @@ var ( // body := Body(fullResp) // content := string(body) Body = P.Tail[*H.Response, []byte] + + FromResponse = P.FromHead[[]byte, *H.Response] + FromBody = P.FromTail[*H.Response, []byte] ) diff --git a/v2/idiomatic/ioresult/generic/gen.go b/v2/idiomatic/ioresult/generic/gen.go deleted file mode 100644 index c26d347..0000000 --- a/v2/idiomatic/ioresult/generic/gen.go +++ /dev/null @@ -1,185 +0,0 @@ -// Code generated by go generate; DO NOT EDIT. -// This file was generated by robots at -// 2025-03-09 23:53:07.5979849 +0100 CET m=+0.009458901 -package generic - - -import ( - ET "github.com/IBM/fp-go/v2/either" -) - -// Eitherize0 converts a function with 0 parameters returning a tuple into a function with 0 parameters returning a [GIOA] -func Eitherize0[GIOA ~func() ET.Either[error, R], F ~func() (R, error), R any](f F) func() GIOA { - e := ET.Eitherize0(f) - return func() GIOA { - return func() ET.Either[error, R] { - return e() - }} -} - -// Uneitherize0 converts a function with 0 parameters returning a tuple into a function with 0 parameters returning a [GIOA] -func Uneitherize0[GIOA ~func() ET.Either[error, R], GTA ~func() GIOA, R any](f GTA) func() (R, error) { - return func() (R, error) { - return ET.Unwrap(f()()) - } -} - -// Eitherize1 converts a function with 1 parameters returning a tuple into a function with 1 parameters returning a [GIOA] -func Eitherize1[GIOA ~func() ET.Either[error, R], F ~func(T1) (R, error), T1, R any](f F) func(T1) GIOA { - e := ET.Eitherize1(f) - return func(t1 T1) GIOA { - return func() ET.Either[error, R] { - return e(t1) - }} -} - -// Uneitherize1 converts a function with 1 parameters returning a tuple into a function with 1 parameters returning a [GIOA] -func Uneitherize1[GIOA ~func() ET.Either[error, R], GTA ~func(T1) GIOA, T1, R any](f GTA) func(T1) (R, error) { - return func(t1 T1) (R, error) { - return ET.Unwrap(f(t1)()) - } -} - -// Eitherize2 converts a function with 2 parameters returning a tuple into a function with 2 parameters returning a [GIOA] -func Eitherize2[GIOA ~func() ET.Either[error, R], F ~func(T1, T2) (R, error), T1, T2, R any](f F) func(T1, T2) GIOA { - e := ET.Eitherize2(f) - return func(t1 T1, t2 T2) GIOA { - return func() ET.Either[error, R] { - return e(t1, t2) - }} -} - -// Uneitherize2 converts a function with 2 parameters returning a tuple into a function with 2 parameters returning a [GIOA] -func Uneitherize2[GIOA ~func() ET.Either[error, R], GTA ~func(T1, T2) GIOA, T1, T2, R any](f GTA) func(T1, T2) (R, error) { - return func(t1 T1, t2 T2) (R, error) { - return ET.Unwrap(f(t1, t2)()) - } -} - -// Eitherize3 converts a function with 3 parameters returning a tuple into a function with 3 parameters returning a [GIOA] -func Eitherize3[GIOA ~func() ET.Either[error, R], F ~func(T1, T2, T3) (R, error), T1, T2, T3, R any](f F) func(T1, T2, T3) GIOA { - e := ET.Eitherize3(f) - return func(t1 T1, t2 T2, t3 T3) GIOA { - return func() ET.Either[error, R] { - return e(t1, t2, t3) - }} -} - -// Uneitherize3 converts a function with 3 parameters returning a tuple into a function with 3 parameters returning a [GIOA] -func Uneitherize3[GIOA ~func() ET.Either[error, R], GTA ~func(T1, T2, T3) GIOA, T1, T2, T3, R any](f GTA) func(T1, T2, T3) (R, error) { - return func(t1 T1, t2 T2, t3 T3) (R, error) { - return ET.Unwrap(f(t1, t2, t3)()) - } -} - -// Eitherize4 converts a function with 4 parameters returning a tuple into a function with 4 parameters returning a [GIOA] -func Eitherize4[GIOA ~func() ET.Either[error, R], F ~func(T1, T2, T3, T4) (R, error), T1, T2, T3, T4, R any](f F) func(T1, T2, T3, T4) GIOA { - e := ET.Eitherize4(f) - return func(t1 T1, t2 T2, t3 T3, t4 T4) GIOA { - return func() ET.Either[error, R] { - return e(t1, t2, t3, t4) - }} -} - -// Uneitherize4 converts a function with 4 parameters returning a tuple into a function with 4 parameters returning a [GIOA] -func Uneitherize4[GIOA ~func() ET.Either[error, R], GTA ~func(T1, T2, T3, T4) GIOA, T1, T2, T3, T4, R any](f GTA) func(T1, T2, T3, T4) (R, error) { - return func(t1 T1, t2 T2, t3 T3, t4 T4) (R, error) { - return ET.Unwrap(f(t1, t2, t3, t4)()) - } -} - -// Eitherize5 converts a function with 5 parameters returning a tuple into a function with 5 parameters returning a [GIOA] -func Eitherize5[GIOA ~func() ET.Either[error, R], F ~func(T1, T2, T3, T4, T5) (R, error), T1, T2, T3, T4, T5, R any](f F) func(T1, T2, T3, T4, T5) GIOA { - e := ET.Eitherize5(f) - return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5) GIOA { - return func() ET.Either[error, R] { - return e(t1, t2, t3, t4, t5) - }} -} - -// Uneitherize5 converts a function with 5 parameters returning a tuple into a function with 5 parameters returning a [GIOA] -func Uneitherize5[GIOA ~func() ET.Either[error, R], GTA ~func(T1, T2, T3, T4, T5) GIOA, T1, T2, T3, T4, T5, R any](f GTA) func(T1, T2, T3, T4, T5) (R, error) { - return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5) (R, error) { - return ET.Unwrap(f(t1, t2, t3, t4, t5)()) - } -} - -// Eitherize6 converts a function with 6 parameters returning a tuple into a function with 6 parameters returning a [GIOA] -func Eitherize6[GIOA ~func() ET.Either[error, R], F ~func(T1, T2, T3, T4, T5, T6) (R, error), T1, T2, T3, T4, T5, T6, R any](f F) func(T1, T2, T3, T4, T5, T6) GIOA { - e := ET.Eitherize6(f) - return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6) GIOA { - return func() ET.Either[error, R] { - return e(t1, t2, t3, t4, t5, t6) - }} -} - -// Uneitherize6 converts a function with 6 parameters returning a tuple into a function with 6 parameters returning a [GIOA] -func Uneitherize6[GIOA ~func() ET.Either[error, R], GTA ~func(T1, T2, T3, T4, T5, T6) GIOA, T1, T2, T3, T4, T5, T6, R any](f GTA) func(T1, T2, T3, T4, T5, T6) (R, error) { - return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6) (R, error) { - return ET.Unwrap(f(t1, t2, t3, t4, t5, t6)()) - } -} - -// Eitherize7 converts a function with 7 parameters returning a tuple into a function with 7 parameters returning a [GIOA] -func Eitherize7[GIOA ~func() ET.Either[error, R], F ~func(T1, T2, T3, T4, T5, T6, T7) (R, error), T1, T2, T3, T4, T5, T6, T7, R any](f F) func(T1, T2, T3, T4, T5, T6, T7) GIOA { - e := ET.Eitherize7(f) - return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7) GIOA { - return func() ET.Either[error, R] { - return e(t1, t2, t3, t4, t5, t6, t7) - }} -} - -// Uneitherize7 converts a function with 7 parameters returning a tuple into a function with 7 parameters returning a [GIOA] -func Uneitherize7[GIOA ~func() ET.Either[error, R], GTA ~func(T1, T2, T3, T4, T5, T6, T7) GIOA, T1, T2, T3, T4, T5, T6, T7, R any](f GTA) func(T1, T2, T3, T4, T5, T6, T7) (R, error) { - return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7) (R, error) { - return ET.Unwrap(f(t1, t2, t3, t4, t5, t6, t7)()) - } -} - -// Eitherize8 converts a function with 8 parameters returning a tuple into a function with 8 parameters returning a [GIOA] -func Eitherize8[GIOA ~func() ET.Either[error, R], F ~func(T1, T2, T3, T4, T5, T6, T7, T8) (R, error), T1, T2, T3, T4, T5, T6, T7, T8, R any](f F) func(T1, T2, T3, T4, T5, T6, T7, T8) GIOA { - e := ET.Eitherize8(f) - return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8) GIOA { - return func() ET.Either[error, R] { - return e(t1, t2, t3, t4, t5, t6, t7, t8) - }} -} - -// Uneitherize8 converts a function with 8 parameters returning a tuple into a function with 8 parameters returning a [GIOA] -func Uneitherize8[GIOA ~func() ET.Either[error, R], GTA ~func(T1, T2, T3, T4, T5, T6, T7, T8) GIOA, T1, T2, T3, T4, T5, T6, T7, T8, R any](f GTA) func(T1, T2, T3, T4, T5, T6, T7, T8) (R, error) { - return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8) (R, error) { - return ET.Unwrap(f(t1, t2, t3, t4, t5, t6, t7, t8)()) - } -} - -// Eitherize9 converts a function with 9 parameters returning a tuple into a function with 9 parameters returning a [GIOA] -func Eitherize9[GIOA ~func() ET.Either[error, R], F ~func(T1, T2, T3, T4, T5, T6, T7, T8, T9) (R, error), T1, T2, T3, T4, T5, T6, T7, T8, T9, R any](f F) func(T1, T2, T3, T4, T5, T6, T7, T8, T9) GIOA { - e := ET.Eitherize9(f) - return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9) GIOA { - return func() ET.Either[error, R] { - return e(t1, t2, t3, t4, t5, t6, t7, t8, t9) - }} -} - -// Uneitherize9 converts a function with 9 parameters returning a tuple into a function with 9 parameters returning a [GIOA] -func Uneitherize9[GIOA ~func() ET.Either[error, R], GTA ~func(T1, T2, T3, T4, T5, T6, T7, T8, T9) GIOA, T1, T2, T3, T4, T5, T6, T7, T8, T9, R any](f GTA) func(T1, T2, T3, T4, T5, T6, T7, T8, T9) (R, error) { - return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9) (R, error) { - return ET.Unwrap(f(t1, t2, t3, t4, t5, t6, t7, t8, t9)()) - } -} - -// Eitherize10 converts a function with 10 parameters returning a tuple into a function with 10 parameters returning a [GIOA] -func Eitherize10[GIOA ~func() ET.Either[error, R], F ~func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) (R, error), T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R any](f F) func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) GIOA { - e := ET.Eitherize10(f) - return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10) GIOA { - return func() ET.Either[error, R] { - return e(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) - }} -} - -// Uneitherize10 converts a function with 10 parameters returning a tuple into a function with 10 parameters returning a [GIOA] -func Uneitherize10[GIOA ~func() ET.Either[error, R], GTA ~func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) GIOA, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R any](f GTA) func(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) (R, error) { - return func(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, t7 T7, t8 T8, t9 T9, t10 T10) (R, error) { - return ET.Unwrap(f(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10)()) - } -} diff --git a/v2/idiomatic/ioresult/generic/ioeither.go b/v2/idiomatic/ioresult/generic/ioeither.go deleted file mode 100644 index 3fe1810..0000000 --- a/v2/idiomatic/ioresult/generic/ioeither.go +++ /dev/null @@ -1,437 +0,0 @@ -// Copyright (c) 2023 - 2025 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 generic - -import ( - "time" - - "github.com/IBM/fp-go/v2/either" - F "github.com/IBM/fp-go/v2/function" - C "github.com/IBM/fp-go/v2/internal/chain" - "github.com/IBM/fp-go/v2/internal/eithert" - FE "github.com/IBM/fp-go/v2/internal/fromeither" - FI "github.com/IBM/fp-go/v2/internal/fromio" - FC "github.com/IBM/fp-go/v2/internal/functor" - IO "github.com/IBM/fp-go/v2/io/generic" - O "github.com/IBM/fp-go/v2/option" -) - -// type IOResult[A any] = func() Either[E, A] - -// Deprecated: -func MakeIO[GA ~func() either.Either[E, A], E, A any](f GA) GA { - return f -} - -// Deprecated: -func Left[GA ~func() either.Either[E, A], E, A any](l E) GA { - return MakeIO(eithert.Left(IO.MonadOf[GA, either.Either[E, A]], l)) -} - -// Deprecated: -func Right[GA ~func() either.Either[E, A], E, A any](r A) GA { - return MakeIO(eithert.Right(IO.MonadOf[GA, either.Either[E, A]], r)) -} - -// Deprecated: -func Of[GA ~func() either.Either[E, A], E, A any](r A) GA { - return Right[GA](r) -} - -// Deprecated: -func MonadOf[GA ~func() either.Either[E, A], E, A any](r A) GA { - return Of[GA](r) -} - -// Deprecated: -func LeftIO[GA ~func() either.Either[E, A], GE ~func() E, E, A any](ml GE) GA { - return MakeIO(eithert.LeftF(IO.MonadMap[GE, GA, E, either.Either[E, A]], ml)) -} - -// Deprecated: -func RightIO[GA ~func() either.Either[E, A], GR ~func() A, E, A any](mr GR) GA { - return MakeIO(eithert.RightF(IO.MonadMap[GR, GA, A, either.Either[E, A]], mr)) -} - -func FromEither[GA ~func() either.Either[E, A], E, A any](e either.Either[E, A]) GA { - return IO.Of[GA](e) -} - -func FromOption[GA ~func() either.Either[E, A], E, A any](onNone func() E) func(o O.Option[A]) GA { - return FE.FromOption( - FromEither[GA, E, A], - onNone, - ) -} - -func ChainOptionK[GA ~func() either.Either[E, A], GB ~func() either.Either[E, B], E, A, B any](onNone func() E) func(func(A) O.Option[B]) func(GA) GB { - return FE.ChainOptionK( - MonadChain[GA, GB, E, A, B], - FromEither[GB, E, B], - onNone, - ) -} - -// Deprecated: -func FromIO[GA ~func() either.Either[E, A], GR ~func() A, E, A any](mr GR) GA { - return RightIO[GA](mr) -} - -// Deprecated: -func MonadMap[GA ~func() either.Either[E, A], GB ~func() either.Either[E, B], E, A, B any](fa GA, f func(A) B) GB { - return eithert.MonadMap(IO.MonadMap[GA, GB, either.Either[E, A], either.Either[E, B]], fa, f) -} - -// Deprecated: -func Map[GA ~func() either.Either[E, A], GB ~func() either.Either[E, B], E, A, B any](f func(A) B) func(GA) GB { - return eithert.Map(IO.Map[GA, GB, either.Either[E, A], either.Either[E, B]], f) -} - -// Deprecated: -func MonadMapTo[GA ~func() either.Either[E, A], GB ~func() either.Either[E, B], E, A, B any](fa GA, b B) GB { - return MonadMap[GA, GB](fa, F.Constant1[A](b)) -} - -// Deprecated: -func MapTo[GA ~func() either.Either[E, A], GB ~func() either.Either[E, B], E, A, B any](b B) func(GA) GB { - return Map[GA, GB](F.Constant1[A](b)) -} - -// Deprecated: -func MonadChain[GA ~func() either.Either[E, A], GB ~func() either.Either[E, B], E, A, B any](fa GA, f func(A) GB) GB { - return eithert.MonadChain(IO.MonadChain[GA, GB, either.Either[E, A], either.Either[E, B]], IO.MonadOf[GB, either.Either[E, B]], fa, f) -} - -// Deprecated: -func Chain[GA ~func() either.Either[E, A], GB ~func() either.Either[E, B], E, A, B any](f func(A) GB) func(GA) GB { - return eithert.Chain(IO.Chain[GA, GB, either.Either[E, A], either.Either[E, B]], IO.Of[GB, either.Either[E, B]], f) -} - -func MonadChainTo[GA ~func() either.Either[E, A], GB ~func() either.Either[E, B], E, A, B any](fa GA, fb GB) GB { - return MonadChain(fa, F.Constant1[A](fb)) -} - -func ChainTo[GA ~func() either.Either[E, A], GB ~func() either.Either[E, B], E, A, B any](fb GB) func(GA) GB { - return Chain[GA](F.Constant1[A](fb)) -} - -// Deprecated: -func MonadChainEitherK[GA ~func() either.Either[E, A], GB ~func() either.Either[E, B], E, A, B any](ma GA, f func(A) either.Either[E, B]) GB { - return FE.MonadChainEitherK( - MonadChain[GA, GB, E, A, B], - FromEither[GB, E, B], - ma, - f, - ) -} - -// Deprecated: -func MonadChainIOK[GA ~func() either.Either[E, A], GB ~func() either.Either[E, B], GR ~func() B, E, A, B any](ma GA, f func(A) GR) GB { - return FI.MonadChainIOK( - MonadChain[GA, GB, E, A, B], - FromIO[GB, GR, E, B], - ma, - f, - ) -} - -func ChainIOK[GA ~func() either.Either[E, A], GB ~func() either.Either[E, B], GR ~func() B, E, A, B any](f func(A) GR) func(GA) GB { - return FI.ChainIOK( - Chain[GA, GB, E, A, B], - FromIO[GB, GR, E, B], - f, - ) -} - -// Deprecated: -func ChainEitherK[GA ~func() either.Either[E, A], GB ~func() either.Either[E, B], E, A, B any](f func(A) either.Either[E, B]) func(GA) GB { - return FE.ChainEitherK( - Chain[GA, GB, E, A, B], - FromEither[GB, E, B], - f, - ) -} - -// Deprecated: -func MonadAp[GB ~func() either.Either[E, B], GAB ~func() either.Either[E, func(A) B], GA ~func() either.Either[E, A], E, A, B any](mab GAB, ma GA) GB { - return eithert.MonadAp( - IO.MonadAp[GA, GB, func() func(either.Either[E, A]) either.Either[E, B], either.Either[E, A], either.Either[E, B]], - IO.MonadMap[GAB, func() func(either.Either[E, A]) either.Either[E, B], either.Either[E, func(A) B], func(either.Either[E, A]) either.Either[E, B]], - mab, ma) -} - -// Deprecated: -func Ap[GB ~func() either.Either[E, B], GAB ~func() either.Either[E, func(A) B], GA ~func() either.Either[E, A], E, A, B any](ma GA) func(GAB) GB { - return eithert.Ap( - IO.Ap[GB, func() func(either.Either[E, A]) either.Either[E, B], GA, either.Either[E, B], either.Either[E, A]], - IO.Map[GAB, func() func(either.Either[E, A]) either.Either[E, B], either.Either[E, func(A) B], func(either.Either[E, A]) either.Either[E, B]], - ma) -} - -// Deprecated: -func MonadApSeq[GB ~func() either.Either[E, B], GAB ~func() either.Either[E, func(A) B], GA ~func() either.Either[E, A], E, A, B any](mab GAB, ma GA) GB { - return eithert.MonadAp( - IO.MonadApSeq[GA, GB, func() func(either.Either[E, A]) either.Either[E, B], either.Either[E, A], either.Either[E, B]], - IO.MonadMap[GAB, func() func(either.Either[E, A]) either.Either[E, B], either.Either[E, func(A) B], func(either.Either[E, A]) either.Either[E, B]], - mab, ma) -} - -// Deprecated: -func ApSeq[GB ~func() either.Either[E, B], GAB ~func() either.Either[E, func(A) B], GA ~func() either.Either[E, A], E, A, B any](ma GA) func(GAB) GB { - return eithert.Ap( - IO.ApSeq[GB, func() func(either.Either[E, A]) either.Either[E, B], GA, either.Either[E, B], either.Either[E, A]], - IO.Map[GAB, func() func(either.Either[E, A]) either.Either[E, B], either.Either[E, func(A) B], func(either.Either[E, A]) either.Either[E, B]], - ma) -} - -// Deprecated: -func MonadApPar[GB ~func() either.Either[E, B], GAB ~func() either.Either[E, func(A) B], GA ~func() either.Either[E, A], E, A, B any](mab GAB, ma GA) GB { - return eithert.MonadAp( - IO.MonadApPar[GA, GB, func() func(either.Either[E, A]) either.Either[E, B], either.Either[E, A], either.Either[E, B]], - IO.MonadMap[GAB, func() func(either.Either[E, A]) either.Either[E, B], either.Either[E, func(A) B], func(either.Either[E, A]) either.Either[E, B]], - mab, ma) -} - -// Deprecated: -func ApPar[GB ~func() either.Either[E, B], GAB ~func() either.Either[E, func(A) B], GA ~func() either.Either[E, A], E, A, B any](ma GA) func(GAB) GB { - return eithert.Ap( - IO.ApPar[GB, func() func(either.Either[E, A]) either.Either[E, B], GA, either.Either[E, B], either.Either[E, A]], - IO.Map[GAB, func() func(either.Either[E, A]) either.Either[E, B], either.Either[E, func(A) B], func(either.Either[E, A]) either.Either[E, B]], - ma) -} - -// Deprecated: -func Flatten[GA ~func() either.Either[E, A], GAA ~func() either.Either[E, GA], E, A any](mma GAA) GA { - return MonadChain(mma, F.Identity[GA]) -} - -// Deprecated: -func TryCatch[GA ~func() either.Either[E, A], E, A any](f func() (A, error), onThrow func(error) E) GA { - return MakeIO(func() either.Either[E, A] { - a, err := f() - return either.TryCatch(a, err, onThrow) - }) -} - -// Deprecated: -func TryCatchError[GA ~func() either.Either[error, A], A any](f func() (A, error)) GA { - return MakeIO(func() either.Either[error, A] { - return either.TryCatchError(f()) - }) -} - -// Memoize computes the value of the provided IO monad lazily but exactly once -// -// Deprecated: -func Memoize[GA ~func() either.Either[E, A], E, A any](ma GA) GA { - return IO.Memoize(ma) -} - -// Deprecated: -func MonadMapLeft[GA1 ~func() either.Either[E1, A], GA2 ~func() either.Either[E2, A], E1, E2, A any](fa GA1, f func(E1) E2) GA2 { - return eithert.MonadMapLeft( - IO.MonadMap[GA1, GA2, either.Either[E1, A], either.Either[E2, A]], - fa, - f, - ) -} - -// Deprecated: -func MapLeft[GA1 ~func() either.Either[E1, A], GA2 ~func() either.Either[E2, A], E1, E2, A any](f func(E1) E2) func(GA1) GA2 { - return eithert.MapLeft( - IO.Map[GA1, GA2, either.Either[E1, A], either.Either[E2, A]], - f, - ) -} - -// Delay creates an operation that passes in the value after some [time.Duration] -// -// Deprecated: -func Delay[GA ~func() either.Either[E, A], E, A any](delay time.Duration) func(GA) GA { - return IO.Delay[GA](delay) -} - -// After creates an operation that passes after the given [time.Time] -// -// Deprecated: -func After[GA ~func() either.Either[E, A], E, A any](timestamp time.Time) func(GA) GA { - return IO.After[GA](timestamp) -} - -// Deprecated: -func MonadBiMap[GA ~func() either.Either[E1, A], GB ~func() either.Either[E2, B], E1, E2, A, B any](fa GA, f func(E1) E2, g func(A) B) GB { - return eithert.MonadBiMap(IO.MonadMap[GA, GB, either.Either[E1, A], either.Either[E2, B]], fa, f, g) -} - -// BiMap maps a pair of functions over the two type arguments of the bifunctor. -// -// Deprecated: -func BiMap[GA ~func() either.Either[E1, A], GB ~func() either.Either[E2, B], E1, E2, A, B any](f func(E1) E2, g func(A) B) func(GA) GB { - return eithert.BiMap(IO.Map[GA, GB, either.Either[E1, A], either.Either[E2, B]], f, g) -} - -// Fold convers an IOEither into an IO -// -// Deprecated: -func Fold[GA ~func() either.Either[E, A], GB ~func() B, E, A, B any](onLeft func(E) GB, onRight func(A) GB) func(GA) GB { - return eithert.MatchE(IO.MonadChain[GA, GB, either.Either[E, A], B], onLeft, onRight) -} - -func MonadFold[GA ~func() either.Either[E, A], GB ~func() B, E, A, B any](ma GA, onLeft func(E) GB, onRight func(A) GB) GB { - return eithert.FoldE(IO.MonadChain[GA, GB, either.Either[E, A], B], ma, onLeft, onRight) -} - -// GetOrElse extracts the value or maps the error -func GetOrElse[GA ~func() either.Either[E, A], GB ~func() A, E, A any](onLeft func(E) GB) func(GA) GB { - return eithert.GetOrElse(IO.MonadChain[GA, GB, either.Either[E, A], A], IO.MonadOf[GB, A], onLeft) -} - -// MonadChainFirst runs the monad returned by the function but returns the result of the original monad -// -// Deprecated: -func MonadChainFirst[GA ~func() either.Either[E, A], GB ~func() either.Either[E, B], E, A, B any](ma GA, f func(A) GB) GA { - return C.MonadChainFirst( - MonadChain[GA, GA, E, A, A], - MonadMap[GB, GA, E, B, A], - ma, - f, - ) -} - -// ChainFirst runs the monad returned by the function but returns the result of the original monad -// -// Deprecated: -func ChainFirst[GA ~func() either.Either[E, A], GB ~func() either.Either[E, B], E, A, B any](f func(A) GB) func(GA) GA { - return C.ChainFirst( - Chain[GA, GA, E, A, A], - Map[GB, GA, E, B, A], - f, - ) -} - -// MonadChainFirstIOK runs the monad returned by the function but returns the result of the original monad -// -// Deprecated: -func MonadChainFirstIOK[GA ~func() either.Either[E, A], GIOB ~func() B, E, A, B any](first GA, f func(A) GIOB) GA { - return FI.MonadChainFirstIOK( - MonadChain[GA, GA, E, A, A], - MonadMap[func() either.Either[E, B], GA, E, B, A], - FromIO[func() either.Either[E, B], GIOB, E, B], - first, - f, - ) -} - -// ChainFirstIOK runs the monad returned by the function but returns the result of the original monad -// -// Deprecated: -func ChainFirstIOK[GA ~func() either.Either[E, A], GIOB ~func() B, E, A, B any](f func(A) GIOB) func(GA) GA { - return FI.ChainFirstIOK( - Chain[GA, GA, E, A, A], - Map[func() either.Either[E, B], GA, E, B, A], - FromIO[func() either.Either[E, B], GIOB, E, B], - f, - ) -} - -// MonadChainFirstEitherK runs the monad returned by the function but returns the result of the original monad -// -// Deprecated: -func MonadChainFirstEitherK[GA ~func() either.Either[E, A], E, A, B any](first GA, f func(A) either.Either[E, B]) GA { - return FE.MonadChainFirstEitherK( - MonadChain[GA, GA, E, A, A], - MonadMap[func() either.Either[E, B], GA, E, B, A], - FromEither[func() either.Either[E, B], E, B], - first, - f, - ) -} - -// ChainFirstEitherK runs the monad returned by the function but returns the result of the original monad -// -// Deprecated: -func ChainFirstEitherK[GA ~func() either.Either[E, A], E, A, B any](f func(A) either.Either[E, B]) func(GA) GA { - return FE.ChainFirstEitherK( - Chain[GA, GA, E, A, A], - Map[func() either.Either[E, B], GA, E, B, A], - FromEither[func() either.Either[E, B], E, B], - f, - ) -} - -// Swap changes the order of type parameters -// -// Deprecated: -func Swap[GEA ~func() either.Either[E, A], GAE ~func() either.Either[A, E], E, A any](val GEA) GAE { - return MonadFold(val, Right[GAE], Left[GAE]) -} - -// FromImpure converts a side effect without a return value into a side effect that returns any -// -// Deprecated: -func FromImpure[GA ~func() either.Either[E, any], IMP ~func(), E any](f IMP) GA { - return F.Pipe2( - f, - IO.FromImpure[func() any, IMP], - FromIO[GA, func() any], - ) -} - -// Defer creates an IO by creating a brand new IO via a generator function, each time -// -// Deprecated: -func Defer[GEA ~func() either.Either[E, A], E, A any](gen func() GEA) GEA { - return IO.Defer(gen) -} - -// Deprecated: -func MonadAlt[LAZY ~func() GIOA, GIOA ~func() either.Either[E, A], E, A any](first GIOA, second LAZY) GIOA { - return eithert.MonadAlt( - IO.Of[GIOA], - IO.MonadChain[GIOA, GIOA], - - first, - second, - ) -} - -// Deprecated: -func Alt[LAZY ~func() GIOA, GIOA ~func() either.Either[E, A], E, A any](second LAZY) func(GIOA) GIOA { - return F.Bind2nd(MonadAlt[LAZY], second) -} - -// Deprecated: -func MonadFlap[GEAB ~func() either.Either[E, func(A) B], GEB ~func() either.Either[E, B], E, B, A any](fab GEAB, a A) GEB { - return FC.MonadFlap(MonadMap[GEAB, GEB], fab, a) -} - -// Deprecated: -func Flap[GEAB ~func() either.Either[E, func(A) B], GEB ~func() either.Either[E, B], E, B, A any](a A) func(GEAB) GEB { - return FC.Flap(Map[GEAB, GEB], a) -} - -// Deprecated: -func ToIOOption[GA ~func() O.Option[A], GEA ~func() either.Either[E, A], E, A any](ioe GEA) GA { - return F.Pipe1( - ioe, - IO.Map[GEA, GA](either.ToOption[E, A]), - ) -} - -// Deprecated: -func FromIOOption[GEA ~func() either.Either[E, A], GA ~func() O.Option[A], E, A any](onNone func() E) func(ioo GA) GEA { - return IO.Map[GA, GEA](either.FromOption[A](onNone)) -} diff --git a/v2/idiomatic/ioresult/generic/types.go b/v2/idiomatic/ioresult/generic/types.go deleted file mode 100644 index 8a229ab..0000000 --- a/v2/idiomatic/ioresult/generic/types.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2025 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 generic - -import "github.com/IBM/fp-go/v2/either" - -type ( - Either[E, A any] = either.Either[E, A] -) diff --git a/v2/idiomatic/ioresult/http/builder/builder.go b/v2/idiomatic/ioresult/http/builder/builder.go index b7c784f..583161e 100644 --- a/v2/idiomatic/ioresult/http/builder/builder.go +++ b/v2/idiomatic/ioresult/http/builder/builder.go @@ -20,46 +20,46 @@ import ( "net/http" "strconv" - E "github.com/IBM/fp-go/v2/either" F "github.com/IBM/fp-go/v2/function" R "github.com/IBM/fp-go/v2/http/builder" H "github.com/IBM/fp-go/v2/http/headers" - "github.com/IBM/fp-go/v2/ioeither" - IOEH "github.com/IBM/fp-go/v2/ioeither/http" - LZ "github.com/IBM/fp-go/v2/lazy" - O "github.com/IBM/fp-go/v2/option" + "github.com/IBM/fp-go/v2/idiomatic/ioresult" + IOEH "github.com/IBM/fp-go/v2/idiomatic/ioresult/http" + "github.com/IBM/fp-go/v2/lazy" + "github.com/IBM/fp-go/v2/option" + "github.com/IBM/fp-go/v2/result" ) func Requester(builder *R.Builder) IOEH.Requester { - withBody := F.Curry3(func(data []byte, url string, method string) IOEither[*http.Request] { - return ioeither.TryCatchError(func() (*http.Request, error) { + withBody := F.Curry3(func(data []byte, url string, method string) IOResult[*http.Request] { + return func() (*http.Request, error) { req, err := http.NewRequest(method, url, bytes.NewReader(data)) if err == nil { req.Header.Set(H.ContentLength, strconv.Itoa(len(data))) H.Monoid.Concat(req.Header, builder.GetHeaders()) } return req, err - }) + } }) - withoutBody := F.Curry2(func(url string, method string) IOEither[*http.Request] { - return ioeither.TryCatchError(func() (*http.Request, error) { + withoutBody := F.Curry2(func(url string, method string) IOResult[*http.Request] { + return func() (*http.Request, error) { req, err := http.NewRequest(method, url, nil) if err == nil { H.Monoid.Concat(req.Header, builder.GetHeaders()) } return req, err - }) + } }) return F.Pipe5( builder.GetBody(), - O.Fold(LZ.Of(E.Of[error](withoutBody)), E.Map[error](withBody)), - E.Ap[func(string) IOEither[*http.Request]](builder.GetTargetURL()), - E.Flap[error, IOEither[*http.Request]](builder.GetMethod()), - E.GetOrElse(ioeither.Left[*http.Request, error]), - ioeither.Map[error](func(req *http.Request) *http.Request { + option.Fold(lazy.Of(result.Of(withoutBody)), result.Map(withBody)), + result.Ap[func(string) IOResult[*http.Request]](builder.GetTargetURL()), + result.Flap[IOResult[*http.Request]](builder.GetMethod()), + result.GetOrElse(ioresult.Left[*http.Request]), + ioresult.Map(func(req *http.Request) *http.Request { req.Header = H.Monoid.Concat(req.Header, builder.GetHeaders()) return req }), diff --git a/v2/idiomatic/ioresult/http/builder/builder_test.go b/v2/idiomatic/ioresult/http/builder/builder_test.go index 1babbe9..f9ccbdf 100644 --- a/v2/idiomatic/ioresult/http/builder/builder_test.go +++ b/v2/idiomatic/ioresult/http/builder/builder_test.go @@ -20,18 +20,18 @@ import ( "net/url" "testing" - E "github.com/IBM/fp-go/v2/either" F "github.com/IBM/fp-go/v2/function" R "github.com/IBM/fp-go/v2/http/builder" + "github.com/IBM/fp-go/v2/idiomatic/ioresult" + E "github.com/IBM/fp-go/v2/idiomatic/result" "github.com/IBM/fp-go/v2/io" - "github.com/IBM/fp-go/v2/ioeither" "github.com/stretchr/testify/assert" ) func TestBuilderWithQuery(t *testing.T) { // add some query withLimit := R.WithQueryArg("limit")("10") - withURL := R.WithUrl("http://www.example.org?a=b") + withURL := R.WithURL("http://www.example.org?a=b") b := F.Pipe2( R.Default, @@ -42,10 +42,10 @@ func TestBuilderWithQuery(t *testing.T) { req := F.Pipe3( b, Requester, - ioeither.Map[error](func(r *http.Request) *url.URL { + ioresult.Map(func(r *http.Request) *url.URL { return r.URL }), - ioeither.ChainFirstIOK[error](func(u *url.URL) io.IO[any] { + ioresult.ChainFirstIOK(func(u *url.URL) io.IO[any] { return io.FromImpure(func() { q := u.Query() assert.Equal(t, "10", q.Get("limit")) diff --git a/v2/idiomatic/ioresult/http/builder/types.go b/v2/idiomatic/ioresult/http/builder/types.go index 695d00a..eacd950 100644 --- a/v2/idiomatic/ioresult/http/builder/types.go +++ b/v2/idiomatic/ioresult/http/builder/types.go @@ -15,8 +15,8 @@ package builder -import "github.com/IBM/fp-go/v2/ioeither" +import "github.com/IBM/fp-go/v2/idiomatic/ioresult" type ( - IOEither[A any] = ioeither.IOEither[error, A] + IOResult[A any] = ioresult.IOResult[A] ) diff --git a/v2/idiomatic/ioresult/http/di/di.go b/v2/idiomatic/ioresult/http/di/di.go deleted file mode 100644 index 8973096..0000000 --- a/v2/idiomatic/ioresult/http/di/di.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2023 - 2025 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 di - -import ( - "net/http" - - DI "github.com/IBM/fp-go/v2/di" - "github.com/IBM/fp-go/v2/ioeither" - IOEH "github.com/IBM/fp-go/v2/ioeither/http" -) - -var ( - // InjHttpClient is the [DI.InjectionToken] for the [http.DefaultClient] - InjHttpClient = DI.MakeTokenWithDefault0("HTTP_CLIENT", ioeither.Of[error](http.DefaultClient)) - - // InjClient is the [DI.InjectionToken] for the default [IOEH.Client] - InjClient = DI.MakeTokenWithDefault1("CLIENT", InjHttpClient.IOEither(), ioeither.Map[error](IOEH.MakeClient)) -) diff --git a/v2/idiomatic/ioresult/http/request.go b/v2/idiomatic/ioresult/http/request.go index 47f1a1f..f6139ef 100644 --- a/v2/idiomatic/ioresult/http/request.go +++ b/v2/idiomatic/ioresult/http/request.go @@ -24,29 +24,22 @@ import ( FL "github.com/IBM/fp-go/v2/file" F "github.com/IBM/fp-go/v2/function" H "github.com/IBM/fp-go/v2/http" - "github.com/IBM/fp-go/v2/ioeither" - IOEF "github.com/IBM/fp-go/v2/ioeither/file" + "github.com/IBM/fp-go/v2/idiomatic/ioresult" + IOEF "github.com/IBM/fp-go/v2/idiomatic/ioresult/file" J "github.com/IBM/fp-go/v2/json" P "github.com/IBM/fp-go/v2/pair" ) type ( - // Requester is a reader that constructs a request - Requester = ioeither.IOEither[error, *http.Request] - - Client interface { - Do(Requester) ioeither.IOEither[error, *http.Response] - } - client struct { delegate *http.Client - doIOE func(*http.Request) ioeither.IOEither[error, *http.Response] + doIOE Kleisli[*http.Request, *http.Response] } ) var ( // MakeRequest is an eitherized version of [http.NewRequest] - MakeRequest = ioeither.Eitherize3(http.NewRequest) + MakeRequest = ioresult.Eitherize3(http.NewRequest) makeRequest = F.Bind13of3(MakeRequest) // specialize @@ -54,92 +47,91 @@ var ( ) // MakeBodyRequest creates a request that carries a body -func MakeBodyRequest(method string, body ioeither.IOEither[error, []byte]) func(url string) ioeither.IOEither[error, *http.Request] { +func MakeBodyRequest(method string, body IOResult[[]byte]) Kleisli[string, *http.Request] { onBody := F.Pipe1( body, - ioeither.Map[error](F.Flow2( + ioresult.Map(F.Flow2( bytes.NewReader, FL.ToReader[*bytes.Reader], )), ) - onRelease := ioeither.Of[error, io.Reader] + onRelease := ioresult.Of[io.Reader] withMethod := F.Bind1of3(MakeRequest)(method) return F.Flow2( F.Bind1of2(withMethod), - ioeither.WithResource[*http.Request](onBody, onRelease), + ioresult.WithResource[*http.Request](onBody, onRelease), ) } -func (client client) Do(req Requester) ioeither.IOEither[error, *http.Response] { +func (client client) Do(req Requester) IOResult[*http.Response] { return F.Pipe1( req, - ioeither.Chain(client.doIOE), + ioresult.Chain(client.doIOE), ) } func MakeClient(httpClient *http.Client) Client { - return client{delegate: httpClient, doIOE: ioeither.Eitherize1(httpClient.Do)} + return client{delegate: httpClient, doIOE: ioresult.Eitherize1(httpClient.Do)} } // ReadFullResponse sends a request, reads the response as a byte array and represents the result as a tuple -func ReadFullResponse(client Client) func(Requester) ioeither.IOEither[error, H.FullResponse] { +func ReadFullResponse(client Client) Kleisli[Requester, H.FullResponse] { return F.Flow3( client.Do, - ioeither.ChainEitherK(H.ValidateResponse), - ioeither.Chain(func(resp *http.Response) ioeither.IOEither[error, H.FullResponse] { + ioresult.ChainEitherK(H.ValidateResponse), + ioresult.Chain(func(resp *http.Response) IOResult[H.FullResponse] { + // var x R.Reader[*http.Response, IOResult[[]byte]] = F.Flow3( + // H.GetBody, + // ioresult.Of, + // IOEF.ReadAll, + // ) + return F.Pipe1( F.Pipe3( resp, H.GetBody, - ioeither.Of[error, io.ReadCloser], - IOEF.ReadAll[io.ReadCloser], + ioresult.Of, + IOEF.ReadAll, ), - ioeither.Map[error](F.Bind1st(P.MakePair[*http.Response, []byte], resp)), + ioresult.Map(F.Bind1st(P.MakePair[*http.Response, []byte], resp)), ) }), ) } // ReadAll sends a request and reads the response as bytes -func ReadAll(client Client) func(Requester) ioeither.IOEither[error, []byte] { +func ReadAll(client Client) Kleisli[Requester, []byte] { return F.Flow2( ReadFullResponse(client), - ioeither.Map[error](H.Body), + ioresult.Map(H.Body), ) } // ReadText sends a request, reads the response and represents the response as a text string -func ReadText(client Client) func(Requester) ioeither.IOEither[error, string] { +func ReadText(client Client) Kleisli[Requester, string] { return F.Flow2( ReadAll(client), - ioeither.Map[error](B.ToString), + ioresult.Map(B.ToString), ) } -// 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) ioeither.IOEither[error, A] { - return ReadJSON[A](client) -} - // readJSON sends a request, reads the response and parses the response as a []byte -func readJSON(client Client) func(Requester) ioeither.IOEither[error, []byte] { +func readJSON(client Client) Kleisli[Requester, []byte] { return F.Flow3( ReadFullResponse(client), - ioeither.ChainFirstEitherK(F.Flow2( + ioresult.ChainFirstEitherK(F.Flow2( H.Response, H.ValidateJSONResponse, )), - ioeither.Map[error](H.Body), + ioresult.Map(H.Body), ) } // ReadJSON sends a request, reads the response and parses the response as JSON -func ReadJSON[A any](client Client) func(Requester) ioeither.IOEither[error, A] { +func ReadJSON[A any](client Client) Kleisli[Requester, A] { return F.Flow2( readJSON(client), - ioeither.ChainEitherK(J.Unmarshal[A]), + ioresult.ChainEitherK(J.Unmarshal[A]), ) } diff --git a/v2/idiomatic/ioresult/http/retry_test.go b/v2/idiomatic/ioresult/http/retry_test.go index 797d1aa..d03bf73 100644 --- a/v2/idiomatic/ioresult/http/retry_test.go +++ b/v2/idiomatic/ioresult/http/retry_test.go @@ -22,10 +22,10 @@ import ( "time" AR "github.com/IBM/fp-go/v2/array" - E "github.com/IBM/fp-go/v2/either" "github.com/IBM/fp-go/v2/errors" F "github.com/IBM/fp-go/v2/function" - "github.com/IBM/fp-go/v2/ioeither" + "github.com/IBM/fp-go/v2/idiomatic/ioresult" + E "github.com/IBM/fp-go/v2/idiomatic/result" O "github.com/IBM/fp-go/v2/option" R "github.com/IBM/fp-go/v2/retry" "github.com/stretchr/testify/assert" @@ -51,7 +51,7 @@ func TestRetryHttp(t *testing.T) { urls := AR.From("https://jsonplaceholder1.typicode.com/posts/1", "https://jsonplaceholder2.typicode.com/posts/1", "https://jsonplaceholder3.typicode.com/posts/1", "https://jsonplaceholder4.typicode.com/posts/1", "https://jsonplaceholder.typicode.com/posts/1") client := MakeClient(&http.Client{}) - action := func(status R.RetryStatus) ioeither.IOEither[error, *PostItem] { + action := func(status R.RetryStatus) IOResult[*PostItem] { return F.Pipe1( MakeGetRequest(urls[status.IterNumber]), ReadJSON[*PostItem](client), @@ -66,6 +66,6 @@ func TestRetryHttp(t *testing.T) { F.Constant1[*PostItem](false), ) - item := ioeither.Retrying(testLogPolicy, action, check)() - assert.True(t, E.IsRight(item)) + _, err := ioresult.Retrying(testLogPolicy, action, check)() + assert.NoError(t, err) } diff --git a/v2/idiomatic/ioresult/http/types.go b/v2/idiomatic/ioresult/http/types.go new file mode 100644 index 0000000..3fb9400 --- /dev/null +++ b/v2/idiomatic/ioresult/http/types.go @@ -0,0 +1,17 @@ +package http + +import ( + "net/http" + + "github.com/IBM/fp-go/v2/idiomatic/ioresult" +) + +type ( + IOResult[A any] = ioresult.IOResult[A] + Kleisli[A, B any] = ioresult.Kleisli[A, B] + Requester = IOResult[*http.Request] + + Client interface { + Do(Requester) IOResult[*http.Response] + } +) diff --git a/v2/ioeither/http/request.go b/v2/ioeither/http/request.go index 47f1a1f..ab337f2 100644 --- a/v2/ioeither/http/request.go +++ b/v2/ioeither/http/request.go @@ -27,7 +27,7 @@ import ( "github.com/IBM/fp-go/v2/ioeither" IOEF "github.com/IBM/fp-go/v2/ioeither/file" J "github.com/IBM/fp-go/v2/json" - P "github.com/IBM/fp-go/v2/pair" + RIOE "github.com/IBM/fp-go/v2/readerioeither" ) type ( @@ -40,7 +40,7 @@ type ( client struct { delegate *http.Client - doIOE func(*http.Request) ioeither.IOEither[error, *http.Response] + doIOE Kleisli[error, *http.Request, *http.Response] } ) @@ -54,7 +54,7 @@ var ( ) // MakeBodyRequest creates a request that carries a body -func MakeBodyRequest(method string, body ioeither.IOEither[error, []byte]) func(url string) ioeither.IOEither[error, *http.Request] { +func MakeBodyRequest(method string, body ioeither.IOEither[error, []byte]) Kleisli[error, string, *http.Request] { onBody := F.Pipe1( body, ioeither.Map[error](F.Flow2( @@ -83,26 +83,23 @@ func MakeClient(httpClient *http.Client) Client { } // ReadFullResponse sends a request, reads the response as a byte array and represents the result as a tuple -func ReadFullResponse(client Client) func(Requester) ioeither.IOEither[error, H.FullResponse] { +func ReadFullResponse(client Client) Kleisli[error, Requester, H.FullResponse] { return F.Flow3( client.Do, ioeither.ChainEitherK(H.ValidateResponse), - ioeither.Chain(func(resp *http.Response) ioeither.IOEither[error, H.FullResponse] { - return F.Pipe1( - F.Pipe3( - resp, - H.GetBody, - ioeither.Of[error, io.ReadCloser], - IOEF.ReadAll[io.ReadCloser], - ), - ioeither.Map[error](F.Bind1st(P.MakePair[*http.Response, []byte], resp)), - ) - }), + ioeither.Chain(F.Pipe1( + F.Flow3( + H.GetBody, + ioeither.Of[error, io.ReadCloser], + IOEF.ReadAll[io.ReadCloser], + ), + RIOE.ChainReaderK[error](H.FromBody), + )), ) } // ReadAll sends a request and reads the response as bytes -func ReadAll(client Client) func(Requester) ioeither.IOEither[error, []byte] { +func ReadAll(client Client) Kleisli[error, Requester, []byte] { return F.Flow2( ReadFullResponse(client), ioeither.Map[error](H.Body), @@ -110,7 +107,7 @@ func ReadAll(client Client) func(Requester) ioeither.IOEither[error, []byte] { } // ReadText sends a request, reads the response and represents the response as a text string -func ReadText(client Client) func(Requester) ioeither.IOEither[error, string] { +func ReadText(client Client) Kleisli[error, Requester, string] { return F.Flow2( ReadAll(client), ioeither.Map[error](B.ToString), @@ -120,12 +117,12 @@ func ReadText(client Client) func(Requester) ioeither.IOEither[error, string] { // 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) ioeither.IOEither[error, A] { +func ReadJson[A any](client Client) Kleisli[error, Requester, A] { return ReadJSON[A](client) } // readJSON sends a request, reads the response and parses the response as a []byte -func readJSON(client Client) func(Requester) ioeither.IOEither[error, []byte] { +func readJSON(client Client) Kleisli[error, Requester, []byte] { return F.Flow3( ReadFullResponse(client), ioeither.ChainFirstEitherK(F.Flow2( @@ -137,7 +134,7 @@ func readJSON(client Client) func(Requester) ioeither.IOEither[error, []byte] { } // ReadJSON sends a request, reads the response and parses the response as JSON -func ReadJSON[A any](client Client) func(Requester) ioeither.IOEither[error, A] { +func ReadJSON[A any](client Client) Kleisli[error, Requester, A] { return F.Flow2( readJSON(client), ioeither.ChainEitherK(J.Unmarshal[A]), diff --git a/v2/ioeither/http/types.go b/v2/ioeither/http/types.go new file mode 100644 index 0000000..0f922d9 --- /dev/null +++ b/v2/ioeither/http/types.go @@ -0,0 +1,11 @@ +package http + +import ( + "github.com/IBM/fp-go/v2/ioeither" + "github.com/IBM/fp-go/v2/readerioeither" +) + +type ( + Kleisli[E, A, B any] = ioeither.Kleisli[E, A, B] + ReaderIOEither[R, E, A any] = readerioeither.ReaderIOEither[R, E, A] +) diff --git a/v2/pair/pair.go b/v2/pair/pair.go index bc93d64..144d93c 100644 --- a/v2/pair/pair.go +++ b/v2/pair/pair.go @@ -59,6 +59,16 @@ func FromTuple[A, B any](t tuple.Tuple2[A, B]) Pair[A, B] { return Pair[A, B]{t.F2, t.F1} } +//go:inline +func FromHead[B, A any](a A) Kleisli[A, B, B] { + return F.Bind1st(MakePair[A, B], a) +} + +//go:inline +func FromTail[A, B any](b B) Kleisli[A, A, B] { + return F.Bind2nd(MakePair[A, B], b) +} + // ToTuple creates a [tuple.Tuple2] from a [Pair]. // The head becomes the first element, and the tail becomes the second element. //