@unwrap not working on normal types

I created type like this and added @unwrap annotation. But the unwrap seems to be not working for normal types. Is there any other way to achieve this?

@unwrap
type t = [ #Str(string) | #Int(int) ]

Please advise.

Hi, Instead of creating a type t can you try to inline it in the external ?
like :

@val
external padLeft: (
  string,
  @unwrap [
    | #Str(string)
    | #Int(int)
  ])
  => string = "padLeft"

@a-c-sreedhar-reddy It is working if I inline in external. But I wish to unwrap for some non external types.

@unwrap only works when it is inline inside an external declaration. It doesn’t work in a normal type definition.

2 Likes

@yawaramin Thank you. Is there any idea or proposal to support it for normal type definitions too?
Example : @unboxed seems to be working for normal type definitions too.

@unwrap and @unboxed are only possible in very specific situations. Even though @unboxed works for normal type definitions, it is only compatible with a variants that have a single constructor with a single argument, and with records that have a single field. For example, this is not possible: @unboxed type t = Str(string) | Int(int).

The reason for these limitations goes back to why variants are “boxed” or “wrapped” in the first place. ReScript code doesn’t have types at runtime, only at compile time. The variant structures keep track of which variant constructor is being used. Without them, the compiled output wouldn’t be type safe.

@unwrap is able to get around the limitations of @unboxed by exchanging them for another limitation: it only works in externals. The reason for this is that the unsafeness isn’t a problem if the values are only sent to external code and never used in ReScript itself.

If you don’t mind sharing a bit more about what problem you’re trying to solve exactly, there’s probably a better solution that doesn’t involve using @unwrap.

1 Like

@johnj Thank you for a detailed explanation. I was trying to add type to something similar to next function in express js. For now, I kind of worked around it by using option<'a>.