flix icon indicating copy to clipboard operation
flix copied to clipboard

Allow multiple collections in `for-yield`

Open magnus-madsen opened this issue 3 years ago • 11 comments

magnus-madsen avatar Jul 11 '22 12:07 magnus-madsen

@mlutze @jaschdoc Question is: how?

magnus-madsen avatar Jul 11 '22 12:07 magnus-madsen

Could a MonadZip class help?

This was added to Haskell for monad comprehensions.

stephentetley avatar Jul 12 '22 16:07 stephentetley

Could a MonadZip class help?

This was added to Haskell for monad comprehensions.

Do you have a link?

magnus-madsen avatar Jul 12 '22 17:07 magnus-madsen

George Giorgidze, et al - Bringing Back Monad Comprehensions

https://db.inf.uni-tuebingen.de/staticfiles/publications/haskell2011.pdf

There is also Jeremy Gibbons's - Comprehending Ringads

https://www.cs.ox.ac.uk/jeremy.gibbons/publications/ringads.pdf

stephentetley avatar Jul 12 '22 18:07 stephentetley

I've implemented Haskell's MonadZip class in Flix - shall I make a PR to add it to the stdlib?

stephentetley avatar Jul 24 '22 10:07 stephentetley

I've implemented Haskell's MonadZip class in Flix - shall I make a PR to add it to the stdlib?

Yes, please! I cannot guarantee we will use it, but I can take a look and try to understand it :)

magnus-madsen avatar Jul 24 '22 10:07 magnus-madsen

Paper looks interesting. Just need to find the time :)

magnus-madsen avatar Jul 24 '22 10:07 magnus-madsen

I've created a PR #4347 - feat: add a MonadZip class, potentially helping issue #4230

I'm looking at adding some more Applicative / Monad traversals to the stdlib so I've included a generic zipWithA function that isn't in the Haskell class.

stephentetley avatar Jul 24 '22 15:07 stephentetley

I am still intrigued by this, I just have not gotten around to it yet.

magnus-madsen avatar Aug 03 '22 20:08 magnus-madsen

I read both papers with great enjoyment. I think a lot of the stuff is a bit too advanced to add to Flix (at least for the moment), but I was happy to see that we are pretty close to where Haskell is at. (I did find one improvement we can make, reflected in https://github.com/flix/flix/issues/4429).

I think we can add MonadZip and syntax for it, e.g. (for (x <- xs | y <- ys), but I am less convinced of whether it would be worth it. (Perhaps we can add the type class, but no comprehension syntax). In any case, none of these papers seems to suggest to me a way to get the flexibility that Scala has, but possible such a system is simply in-expressible in a language like Flix/Haskell.

All this to say, I am not sure exactly what should be "next" for the for-yield/comprehension syntax. Possibly we just leave it where it is at the moment.

magnus-madsen avatar Aug 05 '22 10:08 magnus-madsen

I think this can be done using Iterable along with a type class like below. Materializable.materialize would be wrapped around the entire expression in the weeder (along with a region so it remains pure). That way we're just manipulating / appending iterators which finally materialize to the type we expect. This is partly inspired by Scala's way of handling it via inheritance and just defaulting to Iterable most of the time.

The downside is that we completely abandon the monad implementation.

pub class Materializable[t : Type -> Type] {

    pub def materialize(iter: Iterator[a, r]): t[a] \ Read(r)

}

instance Materializable[List] {

    pub def materialize(iter: Iterator[a, r]): List[a] \ Read(r) =
        Iterator.toList(iter)

}

jaschdoc avatar Aug 24 '22 13:08 jaschdoc

We now have foreach-yield which allows this with iterators.

magnus-madsen avatar Feb 12 '23 11:02 magnus-madsen