I've got a use case that involves type inference, and I'd like to ensure that the data earlier in the program doesn't infer to have a field, in this case style: Str
. Heres a code example of what I'd like to do, but it doesn't compile:
style = "some css"
addStyle : {}a -> { style : Str }a
addStyle = \r -> { r & style }
My though is that the a
would 'eat' the style: Str
, and give the intended behavior
If addStyle
infers that it should return {style: Str, foo: Bool}*
, then it would infer that it should take {foo: Bool}*
. Do I have the wrong mental model, or is this not possible right now?
@Trevor Settles the &
record update syntax cannot change the structure of the record, nor can anything really in Roc. The only way to do that is to manually copy over the fields you want to a new record.
And there's not any way (as far as I know) to do what you're trying here, besides with the current style of record builders
But that's much fancier than what you're trying to do
So the way is to define something like
Element : { tag: Str, content: Str, style: Str }
newElem : Str -> Element
newElem = \tag -> { tag, content: "", style: "" }
addStyle : { style : Str }a -> { style : Str }a
addStyle = \r -> { r & style: "some css" }
coloredDiv =
newElem
|> addStyle
Thanks for the suggestion! I'm doing json parsing, and HTML gen with RTL, so I'm really trying to lean into the type inference. I ended up getting around this by adding a style
key in the json I was taking in
Oh, if you're trying to decode JSON with an optional field, the OptionOrNull
type can handle that https://github.com/lukewilliamboswell/roc-json/blob/main/package/OptionOrNull.roc
Your Roc code will still need the field, but you can avoid needing to add optional fields in the JSON.
addStyle = \r -> { r & "some css" }
should be:
addStyle = \r -> { r & style: "some css" }
But you would need to extract it from the OptionOrNull
type using OptionOrNull.getResult |> Result.withDefault
Yeah, whoops
Last updated: Jul 06 2025 at 12:14 UTC