Skip to content
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

Work on mapping variant cases #37

Merged
merged 13 commits into from Mar 3, 2022

Conversation

MonoidMusician
Copy link
Collaborator

Fixes #36.

This is a work-in progress. In particular, I don't know of a way to come up with the correct map function for the VariantF that is generated from mapSome. Will we have to collect map dictionaries (corresponding to ro row), and then search for it in there?

Note: mapAll has a different implementation from mapSome only because the compiler doesn't solve Union r () r, and it is a constraint I don't want to propagate to the user. Otherwise it would be mapAll r = mapSome r case_.

Also need to write tests. All in good time 😉

@MonoidMusician
Copy link
Collaborator Author

Okay, I added an extensible version (mapSomeExpand r is like mapSome r expand but with more easily solved constraints), I finished up the corresponding functions for VariantF (using a new VariantFMaps), plus some tests, and I did some sanity checking around inference and type errors.

Just need better names and docs. 😁

@natefaubion
Copy link
Owner

natefaubion commented Dec 2, 2018

Thank you for working on this. I haven't reviewed everything in detail, but I have a couple of API thoughts. The type of mapSome is suspiciously similar to on combinators. I think it would be nice to try and extend the existing vocabulary, and maybe have over as an alternative to on. I know you mentioned an issue with case_ which I haven't dived into, but my initial thoughts are that I'd like to be able to say:

case_
  # over _foo (\a -> show a)
  # over _bar (\a -> a + 1)

case_ # overMatch
  { foo: \a -> show a
  , bar: \a -> a + 1
  }

expand
  # over _foo ...
  # over _bar ...

expand # overMatch ...

@natefaubion
Copy link
Owner

I'm not super concerned about catering to the mapAll use-case. You very often want to exhaustively eliminate all the cases (so match vs case_ # onMatch makes sense to me), but I don't think it will be nearly as common to do the same for over to the extent that the extra chars are an inconvenience.

@MonoidMusician
Copy link
Collaborator Author

I'm revisiting this PR since I'm looking at dhall-purescript again. I grepped my code and I only use expandOverMatch and expandTravMatch – I wonder if there might be a nicer API for that. I think type inference is important, which is why I did the tricks with Union. But I'm fairly happy with how it is now. What do you think?

Here's an example usage that I think is important to keep clean:
https://github.com/MonoidMusician/dhall-purescript/blob/0f331a5b1964f3a92113e964e985ce09811ef9ac/src/Dhall/Core/AST/Operations.purs#L21-L29

Also remove redundant variable `r4` and the corresponding constraint
traverse
∷ ∀ r rl ri ro r1 r2 r3 m
. RL.RowToList r rl
⇒ VariantTravCases m rl ri ro
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a small nit, but I think the library tends to use full names where possible, so I'd consider renaming this to VariantTraverseCases

coerceR = unsafeCoerce

-- | Traverse over some labels (with access to the containers) and use
-- | `travers f` for the rest (just changing the index type).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
-- | `travers f` for the rest (just changing the index type).
-- | `traverse f` for the rest (just changing the index type).

@@ -28,8 +34,8 @@ import Data.Enum (class Enum, pred, succ, class BoundedEnum, Cardinality(..), fr
import Data.List as L
import Data.Maybe (Maybe)
import Data.Symbol (class IsSymbol, reflectSymbol)
import Data.Variant.Internal (class Contractable, class VariantMatchCases) as Exports
import Data.Variant.Internal (class Contractable, class VariantMatchCases, class VariantTags, BoundedDict, BoundedEnumDict, VariantCase, VariantRep(..), contractWith, lookup, lookupCardinality, lookupEq, lookupFirst, lookupFromEnum, lookupLast, lookupOrd, lookupPred, lookupSucc, lookupToEnum, unsafeGet, unsafeHas, variantTags)
import Data.Variant.Internal (class Contractable, class VariantMapCases, class VariantMatchCases) as Exports
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this also re-export VariantTraverseCases?

@thomashoneyman
Copy link
Collaborator

I'm still looking through the constraints here, but I have reason to use over and traverse in an updated version of formless and they are working well there.

@thomashoneyman
Copy link
Collaborator

My usage of over and traverse can be seen in the (unreleased) Formless 3, where I'm using them to implement validation functions over variants (example: https://github.com/thomashoneyman/purescript-halogen-formless/blob/37e8a6adf63136fb9b10c5eff1f978e7599730f3/src/Formless.purs#L116). I think they're useful functions and deserve a place in variant!

@natefaubion
Copy link
Owner

I think if y'all are both satisfied with with the implementation/constraints and documentation, then I'm fine with y'all moving forward. I don't currently have any other constructive feedback.

@thomashoneyman
Copy link
Collaborator

Other than my naming and import comments I've mentioned above, this looks perfectly good to me.

@thomashoneyman
Copy link
Collaborator

@natefaubion I'm happy with the current state of things.

@natefaubion
Copy link
Owner

Release away!

@thomashoneyman thomashoneyman merged commit 131d7fb into natefaubion:master Mar 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

add map (like bimap for Either)
3 participants