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

Case struct #7

Closed
wants to merge 4 commits into from
Closed

Conversation

cryogenian
Copy link
Contributor

  • O(1) match
  • Works w/o SProxy :: SProxy "blablabla"
  • Emphasizes duality of variant and record
  • Mappeable case

I don't think that removing on|case_|default is good idea, callbacks might be a bit simpler to understand.

@natefaubion How does this approach look? If you like it, I'll add same thing for Data.Functor.Variant

@cryogenian
Copy link
Contributor Author

BTW, that's what happening when you don't check opened prs :)
This one is kinda duplicated with #6 but with downcast, mapCase and different names.
If #6 is good then I'll reopen this with only record|downcast|variant|mapCase

@MonoidMusician
Copy link
Collaborator

MonoidMusician commented Jul 12, 2017

Hey looks nice! Out of curiosity, what is the benefit of representing variants as singleton records?

Note that you can also extract the key and type directly from a record, something like this:

class RowSingleton label typ row | row -> label typ

instance rowSingleton :: (R.RowToList row (R.Cons label typ (R.Nil))) => RowSingleton label typ row

(uhm the fundeps probably could be made bidirectional with ListToRow ... idk)

I was also thinking maybe handle or handleVariant would be good for the variant–record elimination. Order of arguments is the other thing, so i like what you did with match and ##. :)

[edit] Also, keeping the other functions is a really good idea since they support polymorphism with constraints (and typeclass dictionaries) in ways can't happen with records, where the constraints can't be solved and the variants lose the dictionaries and such. The only reason foo: show works in your test is because you gave cases a type that constraints it to Int ;)

P.S. No worries I've done that before. Also, I don't really know what I'm doing so having something to compare against is good!

@cryogenian
Copy link
Contributor Author

@MonoidMusician Uhm, I just think that we actually have a way of representing SProxy :: SProxy "foo" already, it's just { foo :: Void } (can't be constructed, only type of label matters) and I personally prefer not to involve proxies before they have special syntax.

foo = inj (SProxy :: SProxy "foo") foo 
foo = variant { foo: foo }

You mean you need something like this for constraints, right

cases2   a. Show a  { quux  a  String }
cases2 = { quux: ("tst" <> _ ) <<< show }

quux   a r. Show a  a  Variant (quux  a|r)
quux a = downcast $ variant { quux: a }

so for large Case it would be

case :: forall a b c d. Show a => Show b => Show c => Show d => { ... } 

Looks like compiler is smart enough to union them and handle type constraints

{ quux: ("tst" <> _ ) <<< show } :+: { trololo: \a → eq a a } 

Autotype is

forall t17 t20.
      Show t17 => Eq t20 => { trololo :: t20 -> Boolean
                            , quux :: t17 -> String
                            }

@MonoidMusician
Copy link
Collaborator

sigh, complex issue, here goes ...

yeah, it sometimes works ... it surprised me that quux works, but it does, since the forall quantifies the whole record type. It appears this is what normally happens when binding variables in PSCI at least, such as fooElim = { foo: show }.

but it won't work when the forall quantification happens inside the record, like { foo :: forall a. Show a => a -> String }, which appears to be the default when writing expressions like foo_ ## { foo: show }

nor will it work when not all of the type variables are constrained by the Variant's row, so open rows will probably not work – which was the default in the tests (foo :: forall r. Variant ( foo :: Int | r ) etc.).

and it still won't unify forall c. Category c with Function in the case of id.

so you're right, it works in more cases than I expected! but it's still rather fragile.

@cryogenian
Copy link
Contributor Author

Closing this in favour of #6. @MonoidMusician would you mind adding mapCase (or mapElim) to your pr?

@cryogenian cryogenian closed this Jul 12, 2017
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.

2 participants