How to use the @as decorator?

I am experimenting with the @as decorator with the following code:

type status = [
  @as("GOOD") #Good |
  @as("BAD") #Bad
]

@val external setStatus: status => unit = "setStatus"

setStatus(#Good)

This compiles to:

setStatus("Good");

But I was expecting it would compile to:

setStatus("GOOD");

I suspect I am not using the decorator correctly. Any suggestions on how to correct this?

View in playground

Thanks

After some more investigation I’ve discovered this:

@val external setStatus: @string[
  @as("GOOD") #Good |
  @as("BAD") #Bad
] => unit = "setStatus"

setStatus(#Good)

Which produces:

setStatus("GOOD");

So it seems that:

  1. It’s intended for use with externals, and
  2. the @string decorator is also required.

How does that sound?

Update:

Some more investigation, I see it can be used with record types as well.

type action = {@as("type") type_: string}

let one: action = {type_: "One"}

which produces:

var one = {
  type: "One"
};

So it seems, that the @as decorator:

  1. may be used with record types directly, and
  2. may be used with polymorphic variants on externals with the @string or @int decorators.

How does that sound?

Your two statements are correct.

Poly vars are more flexible with the identifier names for its constructors, so you can easily do it without the as decorator as well, e.g. #GOOD.

Docs on poly vars are currently in the last review phase, so hopefully this will be more clear in the future!

4 Likes

@ryyppy can I not use @as in a defined poly variant type?

type typeopt = @string[
  | @as("required") #Required
  | @as("maxLength") #LengthMax
  | @as("minLength") #LengthMin
  | @as("max") #Max
  | @as("min") #Min
  | @as("validate") #Validate
]

This is at a foreign boundary but the type is used in numerous functions, for example, so writing per function is rough.

Thanks
A

You don’t need @as. Polyvariant values compile to the exact strings as their names in the code. E.g. #required will compile to the string "required" and so on.

The strings I’m trying to capture are long and have whitespace and capitalization so using them as the variant symbols is really annoying.

You can assign them to variables and use those instead.

let foo = #"foo foo"
let bar = #"bar bar"

Of course, in pattern matches you will still need to use the original poly variant literals. But usually pattern matches are only required in a few places.

Or i could use @as? What do you have against @as?

Only the fact that it doesn’t work :wink:

@as will only be reserved for nominal types, for example, record.