-
Notifications
You must be signed in to change notification settings - Fork 23
Generalize #29
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
base: master
Are you sure you want to change the base?
Generalize #29
Conversation
I'm not convinced by this. Strategies are supposed to do evaluation only, and it's pretty clear that a strategy that returns a different type is doing more than evaluation! Moreover, a change this fundamental would break all the Straegies examples in my book. That doesn't necessarily mean we shouldn't ever evolve the API if we have good reason to, I'm just not seeing a strong motivation here. |
I'm sympathetic to your claim that strategies are only supposed to do evaluation. However, I think you closed off that possibility when you made |
A conservative approach: move |
This is a very old library with some historical decisions that we would probably make differently today. Perhaps this change wouldn't break code, but it breaks the docs - the types in the docs now don't match the types in the book, which is likely to cause confusion. Especially because it changes things in a seemingly fundamental way - now a Strategy doesn't have to return the original value, it can return something different. I'm not even sure I understand the impact of that change on how to write parallel code - the point of a Strategy returning the original object is so that the sparks don't get garbage-collected. How does that work if you return a different value? |
That should work just fine with |
|
I wonder if it might be helpful for us to discuss this question in real-time. Do you think you'll have time to do so in the next week or two? |
I think I understand your point that there are useful strategies you can write with this that you couldn't before, and that some things work out more nicely. However, there are also more bad strategies that you can write with this that you couldn't before, e.g. strategies that spark things and then return The whole question of correctness is messy because it's clearly possible to screw up with both the current formulation and your generalized version. However, I do think that the I'd be OK with adding another module for your generalised API so long as we can keep the existing |
I'm totally okay with using a separate module for the underlying more-polymorphic version. Unfortunately, it's quite easy to goof up regardless: do
strat a
return a is an ever-present concern. Perhaps linear types will help eventually. |
It does not pass with the current implementation of `rparWith`.
* Lift the result to avoid always reducing to WHNF. * Rewrite the documentation of `rparWith`. Fixes haskell#35
The same implementation should work for old GHC.
The `(Strategy a, dot)` semigroup generalizes very naturally to a `(Strategy, dot)` semigroupoid. This makes it much easier to fuse maps with strategies.
I agree with Simon here. Do you perhaps have an example where this would be benefitial? |
Generalize most functions from
Strategy a
to a newStrategy' a b
. This didn't actually require any changes to terms, but it gives a much better fusion story.Strategy'
is a profunctor (Kleisli Eval
) as well as a semigroupoid underdot
. Moreover, the extra parametricity makes it easier to see that strategies are implemented correctly—there's no way to forget to apply aStrategy'
if you need its result.Closes #27