Hi folks, I'm not even sure if this is possible nor if it was raised before 
nor if there is already another way of doing something similar. But this is 
something that I've been thinking a lot recently and I'd like to know if it 
is possible and desirable. If it is, I can help with a PR later on.

The "problem":

It is usual to when we have a Struct (specially Ecto.Schemas) to define a 
`@type t()` with the fields. Let's say we have a Struct with a few fields 
like this:

```
defmodule MyStruct do
  defstruct [:a, :b, :c]
  @type t() :: %__MODULE__{
    a: integer() | nil,
    b: integer() | nil,
    c: integer() | nil
  }
```

Now imagine I want to define a function that receives a struct but requires 
one of these fields to be non null. What we have to do right now is to:

```
@type my_struct_with_a() :: %MyStruct{
  a: integer(),
  b: integer() | nil,
  c: integer() | nil
}
```

(Ok, maybe in some cases we do not need to redefine all the other fields 
since they might be irrelevant, but let's assume we actually want to type 
everything)

The proposal:

For map values when we just want to change one field we can do something 
like: ```%MyStruct{my_struct | a: 1}```, but for types this is not possible.

My proposal would be to have something like this:

```
@type my_struct_with_a() :: %MyStruct{MyStruct.t() | a: integer()}
```

That would generate a type with all fields copied from `MyStruct.t()` but 
with `:a` changed to `integer()` instead of `integer() | nil`.

The caveats I see is what to do when the type is not just a map type (maybe 
it is a sum type, maybe it is not even a map, etc).

What do you folks think about this?

Thanks,
Bernardo Amorim

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/b152b04f-3c6b-4052-92aa-d23724ed0f92n%40googlegroups.com.

Reply via email to