-
Notifications
You must be signed in to change notification settings - Fork 2
Add Parallel
typeclass to enable parallel DSLs and parallel code in the monad
#9
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
Conversation
I can rebase these commits if you want (or feel free to squash & merge) -- I'm not sure why the same duplicates are showing up here. I have added parallel constraints on two components to prove that this works, but I wasn't sure what to actually run in parallel to show it off. I can think and add an implementation too if there's something you think would be a good fit for your demo. |
Thanks, this seems quite interesting, but it's a bit confusing. How does |
We commonly need to make a set of network requests and we don't want to perform one, wait for it to finish, then do the next, and so on. Instead, you can take an array of endpoints to hit and then use Now, so long as you're in For example, with a snippet from your code: component :: ∀ f m
. Monad m
=> Parallel f m
=> H.Component HH.HTML Query DialogOptionsLite DialogResult m
component
= H.component
{ initialState: identity
, render
, eval
, receiver: const Nothing
}
where
render :: State -> H.ComponentHTML Query
render dialogOptions = ...
myParallelFunction :: m (Array Int)
myParallelFunction = parTraverse pure [0]
eval :: Query ~> H.ComponentDSL State Query DialogResult m
eval (CloseDialog idx next) = do
arr <- H.lift myParallelFunction
H.raise <<< DialogResult $ idx
pure next You can't write However, the application monad (without this PR) can't do any of this parallel stuff unless we give it an instance of |
That's pretty cool, thanks for the explanation. I'll play with the branch tomorrow for a bit. Maybe one idea would be to keep the instance in the Monad module, and only use it in one sample component that would document how to do this? As opposed to using it in all, even if it's not actually needed and confusing people. What do you think? |
You know what -- on second thought, I realize that the myParallelFunction :: forall f m0. Parallel f m0 => m0 (Array Int)
myParallelFunction = parTraverse pure [0] Then, since HalogenM can perform parallel computations like this, you can freely use this in your Now, any place you want to do this without running the computation in Perhaps there could be a link to this PR as a "further reading" sort of thing, but I think this will cause more confusion than it will help folks building their apps. I've changed my mind, and I think I'm in favor of not merging this PR. Thoughts? |
This PR gives the application monad a
Parallel
instance. The instance requires a related applicative to the app monad, so I've createdExampleA
overParAff
to make this possible. We do the same thing in our application, and I believe it's what SlamData does as well.This instance makes it possible to write functions constrained by one or more DSLs that also is running a parallel computation, and then to use the application monad to run it.