Skip to content

Commit

Permalink
fix: add consistent Delay and After functions to IO
Browse files Browse the repository at this point in the history
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
  • Loading branch information
CarstenLeue committed Jan 12, 2024
1 parent aef0048 commit e742854
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 1 deletion.
23 changes: 23 additions & 0 deletions io/generic/io.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,29 @@ func Delay[GA ~func() A, A any](delay time.Duration) func(GA) GA {
}
}

func after(timestamp time.Time) func() {
return func() {
// check if we need to wait
current := time.Now()
if current.Before(timestamp) {
time.Sleep(timestamp.Sub(current))
}
}
}

// After creates an operation that passes after the given timestamp
func After[GA ~func() A, A any](timestamp time.Time) func(GA) GA {
aft := after(timestamp)
return func(ga GA) GA {
return MakeIO[GA](func() A {
// wait as long as necessary
aft()
// execute after wait
return ga()
})
}
}

// Now returns the current timestamp
func Now[GA ~func() time.Time]() GA {
return MakeIO[GA](time.Now)
Expand Down
10 changes: 10 additions & 0 deletions io/io.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,13 @@ func MonadFlap[B, A any](fab IO[func(A) B], a A) IO[B] {
func Flap[FAB ~func(A) B, GFAB ~func() FAB, GB ~func() B, A, B any](a A) func(IO[func(A) B]) IO[B] {
return G.Flap[func(A) B, IO[func(A) B], IO[B], A, B](a)
}

// Delay creates an operation that passes in the value after some delay
func Delay[A any](delay time.Duration) func(IO[A]) IO[A] {
return G.Delay[IO[A]](delay)
}

// After creates an operation that passes after the given timestamp
func After[A any](timestamp time.Time) func(IO[A]) IO[A] {
return G.After[IO[A]](timestamp)
}
7 changes: 6 additions & 1 deletion ioeither/generic/ioeither.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,11 +207,16 @@ func MapLeft[GA1 ~func() ET.Either[E1, A], GA2 ~func() ET.Either[E2, A], E1, E2,
return F.Bind2nd(MonadMapLeft[GA1, GA2, E1, E2, A], f)
}

// Delay creates an operation that passes in the value after some delay
// Delay creates an operation that passes in the value after some [time.Duration]
func Delay[GA ~func() ET.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]
func After[GA ~func() ET.Either[E, A], E, A any](timestamp time.Time) func(GA) GA {
return IO.After[GA](timestamp)
}

func MonadBiMap[GA ~func() ET.Either[E1, A], GB ~func() ET.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, ET.Either[E1, A], ET.Either[E2, B]], fa, f, g)
}
Expand Down
12 changes: 12 additions & 0 deletions ioeither/ioeither.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
package ioeither

import (
"time"

ET "github.com/IBM/fp-go/either"
I "github.com/IBM/fp-go/io"
G "github.com/IBM/fp-go/ioeither/generic"
Expand Down Expand Up @@ -276,3 +278,13 @@ func Flap[E, B, A any](a A) func(IOEither[E, func(A) B]) IOEither[E, B] {
func ToIOOption[E, A any](ioe IOEither[E, A]) IOO.IOOption[A] {
return G.ToIOOption[IOO.IOOption[A]](ioe)
}

// Delay creates an operation that passes in the value after some delay
func Delay[E, A any](delay time.Duration) func(IOEither[E, A]) IOEither[E, A] {
return G.Delay[IOEither[E, A]](delay)
}

// After creates an operation that passes after the given [time.Time]
func After[E, A any](timestamp time.Time) func(IOEither[E, A]) IOEither[E, A] {
return G.After[IOEither[E, A]](timestamp)
}
5 changes: 5 additions & 0 deletions iooption/generic/iooption.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,11 @@ func Delay[GA ~func() O.Option[A], A any](delay time.Duration) func(GA) GA {
return IO.Delay[GA](delay)
}

// After creates an operation that passes after the given [time.Time]
func After[GA ~func() O.Option[A], A any](timestamp time.Time) func(GA) GA {
return IO.After[GA](timestamp)
}

// Fold convers an IOOption into an IO
func Fold[GA ~func() O.Option[A], GB ~func() B, A, B any](onNone func() GB, onSome func(A) GB) func(GA) GB {
return optiont.MatchE(IO.MonadChain[GA, GB, O.Option[A], B], onNone, onSome)
Expand Down
12 changes: 12 additions & 0 deletions iooption/iooption.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
package iooption

import (
"time"

ET "github.com/IBM/fp-go/either"
I "github.com/IBM/fp-go/io"
IO "github.com/IBM/fp-go/io"
Expand Down Expand Up @@ -164,3 +166,13 @@ func MonadChainFirstIOK[A, B any](first IOOption[A], f func(A) IO.IO[B]) IOOptio
func ChainFirstIOK[A, B any](f func(A) IO.IO[B]) func(IOOption[A]) IOOption[A] {
return G.ChainFirstIOK[IOOption[A], IO.IO[B]](f)
}

// Delay creates an operation that passes in the value after some delay
func Delay[A any](delay time.Duration) func(IOOption[A]) IOOption[A] {
return G.Delay[IOOption[A]](delay)
}

// After creates an operation that passes after the given [time.Time]
func After[A any](timestamp time.Time) func(IOOption[A]) IOOption[A] {
return G.After[IOOption[A]](timestamp)
}

0 comments on commit e742854

Please sign in to comment.