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

Construct a variant from a record #43

Open
joneshf opened this issue Jul 31, 2019 · 3 comments · May be fixed by #44
Open

Construct a variant from a record #43

joneshf opened this issue Jul 31, 2019 · 3 comments · May be fixed by #44

Comments

@joneshf
Copy link
Contributor

joneshf commented Jul 31, 2019

Is there any interest in adding something that allows constructing a variant with a singleton record?

foo :: Data.Variant.Variant (bar :: Int, baz :: String, qux :: Boolean)
foo = Data.Variant.fromRecord { qux: true }

The motivation here is that using SProxy _ is a bit more cumbersome than seems necessary. Record syntax is a bit more lightweight to toss around.

It seems like fromRecord could be implemented like:

module Data.Variant where

class FromRecord (list :: Prim.RowList.RowList) record variant where
  fromRecord' :: forall proxy. proxy list -> Record record -> Variant variant

instance fromRecordSingleton ::
  ( Data.Symbol.IsSymbol label
  , Prim.Row.Cons label value () record
  , Prim.Row.Cons label value variant' variant
  ) =>
  FromRecord (Prim.RowList.Cons label value Prim.RowList.Nil) record variant
    where
      fromRecord' _ record = inj label (Record.get label record)
        where
        label :: Data.Symbol.SProxy label
        label = Data.Symbol.SProxy

fromRecord ::
  forall list record variant.
  Prim.RowList.RowToList record list =>
  FromRecord list record variant =>
  Record record ->
  Variant variant
fromRecord = fromRecord' (Type.Data.RowList.RLProxy :: _ list)

Might want some fundeps, dunno. If we want to be helpful, adding some custom error messages for using the wrong size record should be possible as well:

else instance fromRecordMultiple ::
  ( Prim.TypeError.Fail ?someErrorMessageAboutMultipleFieldsInTheRecord
  ) =>
  FromRecord (Prim.RowList.Cons label value list) record variant
    where
      fromRecord' proxy record = fromRecord' proxy record
else instance fromRecordEmpty ::
  ( Prim.TypeError.Fail ?someErrorMessageAboutTheEmptyRecord
  ) =>
  FromRecord Prim.RowList.Nil record variant
    where
      fromRecord' proxy record = fromRecord' proxy record
@safareli
Copy link

safareli commented Jul 31, 2019

Looks great!

Maybe as name use injRecord or injR so it's closer to current vocabulary

@natefaubion
Copy link
Owner

I would be open to this. See natefaubion/purescript-checked-exceptions#6 (comment)

@safareli safareli linked a pull request Oct 3, 2019 that will close this issue
@safareli
Copy link

safareli commented Oct 3, 2019

here you go #44

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 a pull request may close this issue.

3 participants