# Alias redefinition

**URL:** <https://forum.crystal-lang.org/t/alias-redefinition/5024>\
**Category:** Help & Support\
**Created:** [October 21, 2022, 9:18pm UTC](https://forum.crystal-lang.org/t/alias-redefinition/5024 "2022-10-21T21:18:29Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![hutou](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/hutou/32/1337_2.png) [@hutou](https://forum.crystal-lang.org/u/hutou)\
**Post date:** [October 21, 2022, 9:18pm UTC](https://forum.crystal-lang.org/t/alias-redefinition/5024/1 "2022-10-21T21:18:29Z")

</div>

HI,  
In a shard i am developping, I have to use an alias for a union of types that will only be really defined when it is used in the final application

Example code :

Shard panel:

```auto
module Panel
...
include Enumerable(UserType)
...
end

```

User Application:

```auto
alias UserType = String | Int32 | MyType1 | MyType2 ...
require "panel"
...

```

By declaring the `alias` **before** the `require` in the app source code, the compilation proceeds normally and the application works correctly.

However, there are some drawbacks in the shard development process, for example:.

- In the editor (vim), the lack of UserType definition generates alerts (not blocking, but annoying)
- crystal doc does not generate the documentation, because of the missing UserType definition.

Is there an approach to this type of problem? A redefinition of alias in the user code ?

Thanks

---

<div class="post-metadata">

**Author:** ![jgaskins](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/jgaskins/32/2449_2.png) [@jgaskins](https://forum.crystal-lang.org/u/jgaskins)\
**Post date:** [October 22, 2022, 2:32am UTC](https://forum.crystal-lang.org/t/alias-redefinition/5024/2 "2022-10-22T02:32:19Z")

</div>

Would it make sense for `Panel` to be a generic type so you can inject the `Enumerable` type?

```crystal
module Panel(T)
  include Enumerable(T)
end

```

And then, assuming `Panel` is a mixin:

```crystal
class MyClass
  include Panel(UserType)
end

```

---

<div class="post-metadata">

**Author:** ![hutou](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/hutou/32/1337_2.png) [@hutou](https://forum.crystal-lang.org/u/hutou)\
**Post date:** [October 22, 2022, 10:05am UTC](https://forum.crystal-lang.org/t/alias-redefinition/5024/3 "2022-10-22T10:05:58Z")

</div>

Unfortunately, module Panel is not meant to be used as a mixin, but as an external library.

Now, on reflection, this chicken-and-egg problem could simply be solved if the `UserType` type could be deduced from the generic `Enumerable(T)` type.

For example, given the following class:

```auto
class Test(T)
  def initialize(@data : Enumerable(T))
    p T
  end
end

t = Test.new({'a' => [1, "A", 3.14]})

```

the output is:  
`Tuple(Char, Array(Float64 | Int32 | String))`

How could I infer `UserType` from `T` so that it equals the union of `Char | Float64 | Int32 | String` ?

---

<div class="post-metadata">

**Author:** ![jgaskins](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/jgaskins/32/2449_2.png) [@jgaskins](https://forum.crystal-lang.org/u/jgaskins)\
**Post date:** [October 22, 2022, 11:20am UTC](https://forum.crystal-lang.org/t/alias-redefinition/5024/4 "2022-10-22T11:20:59Z")

</div>

Would something like this work?

```crystal
class Test(T)
  def initialize(@data : Enumerable({Char, Array(T)}))
    {% if T < Union(Char | Float64 | Int32 | String) %}
      p T
    {% else %}
      {% raise "Test type must be Char, Float64, Int32, or String. Got: #{T}" %}
    {% end %}
  end
end

t = Test.new({'a' => [1, "A", 3.14, "hi"]})

```

---

<div class="post-metadata">

**Author:** ![straight-shoota](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/straight-shoota/32/36_2.png) [@straight-shoota](https://forum.crystal-lang.org/u/straight-shoota)\
**Post date:** [October 22, 2022, 1:59pm UTC](https://forum.crystal-lang.org/t/alias-redefinition/5024/5 "2022-10-22T13:59:28Z")

</div>

What is `T` and what is `UserType`? Your examples each ever contain only one of them. So it’s unclear what the connection would be.

---

<div class="post-metadata">

**Author:** ![hutou](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/hutou/32/1337_2.png) [@hutou](https://forum.crystal-lang.org/u/hutou)\
**Post date:** [October 22, 2022, 8:19pm UTC](https://forum.crystal-lang.org/t/alias-redefinition/5024/6 "2022-10-22T20:19:05Z")

</div>

Hmm, not easy to explain in a simple and concise way

Say I have a grid, with `n` columns and `m` lines, which I want to fill with data from an `Enumerable` (whatever contents).  
Of course, each entry in the `Enumerable` will correspond to a line in the grid, but I now need to define which data should appear in which column.  
To do this, I put the definition of each column in an array, including at least a `label` and a `Proc` to extract the data.  
I then come to the following definitions in (pseudo)code:

```auto
class Column(T)
  def initialize(@label : String, @extract : T -> ???)
  end
end
 
class Line(T)
  include Enumerable(???)
  def initialize(@grid : Grid(T), @source : T)
  end
  def each
    yield ...
  end   
end
 
class Grid(T)
  include Enumerable(Line(T))
  def initialize(@sources : Enumerable(T))
    @columns = {} of String => Column(T)
  end
  def each
    yield ...
  end  
  def add_column(label, &extractor)
  	@columns[label] = extractor
  end
end

```

Say I have the following Enumerable as sources : `data = {'a' => [1, "A", 3.14], 'b' => [2, "Z", 2.718]}`  
So I define the grid with :

```auto
g = Grid.new(data)
g.add_column("col 1") {|k, v| k}
g.add_column("col 2") {|k, v| v[2]}

```

and printing the grid would give :

> a 3.14  
> b 2.718

In the code above, I have represented the type of data I am looking for with `???`  
In this example, the type `???` is `Char | Float64 | Int32 | String` while `T` is `Tuple(Char, Array(Float64 | Int32 | String))`

but with for example, a source data of `[['a', 3.14], ['b', 2.718]]`, it would have been only `Char | Float64`

So, my question is, in this case, is it possible to derive an union of simple types from any type of `Enumerable(T)` to avoid to have to define manually an alias in the application source code with the drawbacks I mentioned in my first post?

Hope it’s more clear ?

Thanks

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [October 22, 2022, 9:19pm UTC](https://forum.crystal-lang.org/t/alias-redefinition/5024/7 "2022-10-22T21:19:21Z")

</div>

It seems that you are describing a solution. It would be better to instead describe the problem. Why you need to pass the data and columns information separately? And, ultimately what is the grid going to be used for? What is it modeling?

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [October 22, 2022, 9:19pm UTC](https://forum.crystal-lang.org/t/alias-redefinition/5024/8 "2022-10-22T21:19:53Z")

</div>

Maybe the most important question is: what program are you building?

---

<div class="post-metadata">

**Author:** ![hutou](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/hutou/32/1337_2.png) [@hutou](https://forum.crystal-lang.org/u/hutou)\
**Post date:** [October 23, 2022, 1:53pm UTC](https://forum.crystal-lang.org/t/alias-redefinition/5024/9 "2022-10-23T13:53:09Z")

</div>

Well, it looks complicated apparently.  
So I think I’ll stick with the version that works!
