GADT as an optional argument


I have a function which takes a GADT as an argument but I’d like it to have a default value. It’s useful to me because I could add functionality to my API without breaking backwards compatibility and I could make the most common case (by far) less verbose.

type _ stringOrInt =
  | String: string stringOrInt
  | Int: int stringOrInt
let stringOrIntStyle :
  'a . string -> ?valueUnit:'a stringOrInt -> 'a -> style =
  fun (type a) key ?valueUnit:((valueUnit : a stringOrInt)=String) value  ->
         match valueUnit with
         | String  -> StringStyle (key, value)
         | Int  -> IntStyle (key, value)

It currently doesn’t compile. If I cast String, the default value, with Obj.magic it does compile but the code becomes unsafe because the type of value is not bound by the GADT.

My hopes are low but is it somehow possible to have a default value here?

PS; sorry, that I didn’t use snake_case here but it’s from my BuckleScript/Reason project

i tried a little; a simple function with only an optional GADT argument on its own worked just fine for me. the problem with yours seems to be that the type 'a is constrained to string or int by the definition of the GADT and this constraint has to apply to the input signature of the function as well. so the function is polymorphic but implicitly only over string or int. i don’t think that it works that way, i would think it is either fully polymorphic of monomorphic. you could achieve the latter by putting the value argument also into the GADT or making another wrapper GADT which combines an 'a stringOrInt with an 'a value. i may be wrong.

Thank you, I think your suggestions would work but I would achieve my “goal” this way (although it’s not anything critical) .

This topic covers this:

1 Like