-
-
Notifications
You must be signed in to change notification settings - Fork 89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Translating types #11
Comments
I 100% agree. We are looking for a way to implement common interfaces. Any idea appreciated ;) |
As it is now:
Could this work?
|
Not without declaring the R type in the struct definition iirc
…On Fri, Sep 16, 2022, 22:01 Elle Mundy ***@***.***> wrote:
As it is now:
func (o Option[T]) FlatMap(mapper func(value T) Option[T]) Option[T] {
if o.isPresent {
return mapper(o.value)
}
return None[T]()
}
Could this work?
func (o Option[T]) FlatMap[R](mapper func(value T) Option[R]) Option[R] {
if o.isPresent {
return mapper(o.value)
}
return None[R]()
}
—
Reply to this email directly, view it on GitHub
<#11 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAUTW3AFM6OHBPVOM73WUTV6TGZFANCNFSM6AAAAAAQDOKIBA>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Ah, right you are |
A while back, I had written a similar type (though I named my package type Option[T any] struct {
value *T
}
func Map[T any, U any](o Option[T], fn func(T) U) Option[U] {
switch {
case o.IsSome():
return Some(fn(o.Unwrap()))
default:
return None[U]()
}
} Though, it might be tricky to make that work for both |
That signature is similar to lo’s |
We're starting to look into using this lib in our Go stack. The lack of mapping/transform functions for the different algenraic data types is a bit f nuisance, so I really support the idea of doing something about that. IMO, the only way of doing that (due to the already mentioned (silly) constraints in the Go generics implementation for types), is to add top level functions for each type. Internally, we for example have defined a function something like this: func TransformEither[L, R, T any](either mo.Either[L, R], tLeft func(L) T, tRight func(R) T) T {
if either.IsLeft() {
return tLeft(either.MustLeft())
}
return tRight(either.MustRight())
} would it make sense to add a package |
@samber I'd be happy to contribute some PRs if we can agree on a direction for the structure. |
I guess the limiting factor is that go does not allow type parameters on methods? If that was possible, transforming the value would be simple. There is an ongoing (been going on for years) discussion about adding support for this, but no conclusion :S Basically they haven't found any practical way of doing it because of how Golang implements generics (similar to how C++ templates). If they disallow type parameters for interface methods, it can be done though. I am hoping they will implement that in some version of the language :S Stack overflow with discussion about the same thing being impossible in C++ Ofc, in other languages that are relying on erasure instead of code generation for generics (which is inferior in many other ways), the problem goes away entirely :S |
@tbflw @samber I've also been thinking the same thing and would be happy to contribute PRs that add functors for the various types. an adhoc example of functor
inspiration coming from https://typelevel.org/cats/typeclasses/functor.html (edit/late addition to my comment): While it would be ideal to use type parameters on methods, since Go doesn't support that, I think that creating top level functors (maybe scoped by packages that are named by types?) is an acceptable best-efforts alternative. |
At this moment we cant use monads to translate between different Result monad types.
Ex
Ok(42).FlatMap(func(int) Result[string] { return Ok("wont work") })
because of the single type constraint introduced in the signature.
It wold be very useful if we can perform translations.
A way to do this is to detach FlatMap from result and make the signature like this
func [T, U any] FlatMap(func(T) Result[U]) Result[U]
Or maybe even
func [T, U any] FlatMap(func(T)(U, error)) Result[U]
I understand why this is not done here, it is because of the go generics restriction not to introduce new types in a struct methods. At the time being all types that are used in the struct methods must be declared in the struct definition.
Also func(T) Result[U] is not a correct functor interface, for go maybe func(t) (U, error) would be more appropriate but tbh returning result feels right. The cons is that it will be hard to define universal interface that will work across all of the monads.
The text was updated successfully, but these errors were encountered: