alpaca-lang / alpaca

Functional programming inspired by ML for the Erlang VM
Other
1.44k stars 48 forks source link

Treat types with a single unqualified member as aliases #234

Closed j14159 closed 6 years ago

j14159 commented 6 years ago

Something like:

type my_rec = {x: int, y: string}

is currently represented as:

#adt{name = <<"my_rec">>, vars = [], members = [#t_record{ ... }]

in the typer. This causes issues when used by another type in a record transformation. Here's a failing test example:

    %% A simplified example based on some Alpaca AST changes I would like to
    %% make:
    Code =
        "module rtrt \n"
        "type my_rec = {x: int, y: string} \n"
        "type a = A my_rec \n"
        "let get_x A {x=x} = x \n"
        "let rebind_y A rec y = A {y=y | rec}",

    ?assertMatch({ok, #alpaca_module{}},
                 module_typ_and_parse(Code)).

This crashes for two reasons:

The record dumped to the console:

{adt,<<"my_rec">>,rtrt,[],
  [{t_record,false,
   [{t_record_member,x,t_int},
    {t_record_member,y,t_string}],
   {unbound,t5,0}}]}

I'd like to make the change that any user-defined type with a single member and no type constructor will be a type alias internally, not an ADT.

lepoetemaudit commented 6 years ago

In Elm this distinction is made explicit with the alias keyword, i.e.

type alias MyRecord = { a : Int, b : String }

type MyAdt = One | Two | Three

I think the rules you give to distinguish type aliases from ADTs are clear enough, though.