tweag / nickel

Better configuration for less
https://nickel-lang.org/
MIT License
2.23k stars 85 forks source link

Add functions to create and generically unwrap enum variants #1898

Closed yannham closed 3 weeks ago

yannham commented 2 months ago

Is your feature request related to a problem? Please describe. Nickel 1.5 introduced enum variants. Thanks to pattern matching and destructuring, there's a number of things you can do already, but there are still operations that are impossible to encore currently. Those operations are the transformations that are generic in the tag. Typically, one can't implement a function that takes a variant whose argument is a record, remove a field, and return the result in a variant with the same tag. That is:

remove_in_variant "bar" ('Foo {bar=1}) == 'Foo {}
remove_in_variant "bar" ('Bar {bar=1,qux=1}) == 'Bar {qux=1}

Describe the solution you'd like

While pattern matching and destructuring is most principled (and typeable way) to manipulate enum when applicable, add functions to unwrap and to wrap the content of enum variants, that is:

std.enum.unwrap ('<tag> arg) := arg
std.enum.variant tag arg := '<tag> arg

The names are up for bikeshedding.

yannham commented 2 months ago

I guess, if we do so, we can probably add a map function as well, which is just fun f enum => enum |> std.enum.unwrap |> f |> std.enum.variant (std.enum.tag enum).

Another possibility for unwrap would be to return the tag as well, like unwrap: Enum -> {tag | String, arg | optional}.

yannham commented 3 weeks ago

Implemented in #1939.