free icon indicating copy to clipboard operation
free copied to clipboard

Add methods `or` and `and` for concurrency

Open safareli opened this issue 8 years ago • 11 comments

I was thinking what if instead of ignoring law <*> = ap make Free lawfull but add two methods or and and which could be used when actions should be resolved concurrently.

possibly change foldmap to somethink like this:

 -- don't  quite like the field names
type Interpreter i m a =
  { or   :: m c -> m c -> m  c
  , and  :: m c -> m b -> m (c, b)
  , fold :: i   -> m a
  , type :: TypeRep m -- we need to access `of` and `chainRec`.
  }

interpret :: (ChainRec m, Monad m) => Free i a ~> Interpreter i m a -> m a

we would need to change type of Free to:

data Free i a
-  = Ap { x: (Free i b), y: (Free i (b -> a)) }
+  = And { x: (Free i a), y: (Free i b) }
+  | Or { x: (Free i a), y: (Free i a) }
   | Pure { x: a }
   | Lift { x: i, f: (b -> a) }
   | Chain { x: (Free i b), f: (b -> (Free i a)) }

it would also change description of the repo

-Combination of a free applicative functor and free monad
+Free Monad with simple concurrency constructs

With this constructs we could also have this static methods on Free:

Free.concurrently :: [Free i a] -> Free i [a]
Free.race :: [Free i a] -> Free i a
Free.sequentially :: [Free i a] -> Free i [a]

safareli avatar Oct 20 '16 11:10 safareli

@jdegoes I would love to hear your thoughts on this.

safareli avatar Oct 20 '16 11:10 safareli

@safareli if you haven't seen it already, there's some discussion of concurrent free applicatives in section 5.4 of "There is no fork" http://dl.acm.org/citation.cfm?id=2628144 If Free is no longer a (concurrent) Applicative, it wouldn't be possible to use generic functions like lift with it, which would be a bit of a shame.

kwijibo avatar Oct 20 '16 12:10 kwijibo

url is not working

safareli avatar Oct 20 '16 12:10 safareli

(amended the link - from there, follow the link to the pdf)

kwijibo avatar Oct 20 '16 12:10 kwijibo

If Free is no longer a (concurrent) Applicative, it wouldn't be possible to use generic functions like lift with it, which would be a bit of a shame.

Free is concurrent if target monad is not lawful. so if in perfect world all Task/Futures are lawful then there will be no concurrency benefits from dispatching to ap of target monad.

if we add some minimal concurrency constructs to Free and then it would be possible to still fold it concurrently when target monad is lawful.

related issue: fantasy-land#179

safareli avatar Oct 20 '16 12:10 safareli

will take a look at that paper but haxl is not lawful as well

safareli avatar Oct 20 '16 12:10 safareli

I like it. FWIW, or is often called race, and and is equivalent to a function normally called par. See purescript-parallel, for example.

jdegoes avatar Oct 20 '16 13:10 jdegoes

MonadPar and MonadRace from purescript-parallel are what we need in JS will create an issue FL for that, thanks!

safareli avatar Oct 20 '16 13:10 safareli

If we had that algebras in FL then foldMap would become:

foldMap :: (ChainRace m, ChainRec m, Monad m) => Free i a ~> (i -> m a) -> TypeRep m -> m a

And with something like Parallel we can transform (Monad m, ChainRace m) into just Applicative which is concurant (i.e. we would be able to use lift and general functions over Applicative while still be concurant)

safareli avatar Oct 20 '16 13:10 safareli

Currently i'm porting the recent version of haskell-free-concurrent. Before I did not understood the implementation because of Lenses and it's strange operators, but now I did another try and i got it 🎉

safareli avatar Nov 03 '16 16:11 safareli