Congratulations on this awesome article and kudos for the development of GALA. I think you are spot on pinpointing the challenges one faces when trying to apply functional patterns to pure go. In particular the lack of function overloading that leads to PipeXXX in fp-go is a real pain point. And so is the limitted types system. Go 1.24 has made a significant step forward by allowing type aliases for generic types. This makes switching between monads much simpler.
As the author of fp-go I would like to point out that the syntax of the fp-go examples can be simplified.
For example instead of
result := function.Pipe3(
O.Some(42),
O.Map(func(x int) int { return x * 2 }),
O.Chain(func(x int) O.Option[int] {
if x > 50 { return O.Some(x) }
return O.None[int]()
}),
O.GetOrElse(func() int { return 0 }),
)
I would write
result := F.Pipe3(
O.Some(42),
O.Map(N.Mul(2)),
O.Filter(N.MoreThan(50)),
O.GetOrElse(L.Of(0)),
)
Actually in the spirit of the library I would avoid writing a pipeline but rather a new function that implements the pipeline and that can then be reused and composed like this:
endo := F.Flow4(
O.Some,
O.Map(N.Mul(2)),
O.Filter(N.MoreThan(50)),
O.GetOrElse(L.Of(0)),
)
fmt.Println(endo(42))
fmt.Println(endo(2))
As a bonus such a function can be unit tested.
Thanks for your splendid work and for spreading the idea of functional patterns across the go community!
Carsten