# How to know the concrete type of generics?

**URL:** <https://forum.crystal-lang.org/t/how-to-know-the-concrete-type-of-generics/1452>\
**Category:** Help & Support\
**Created:** [December 6, 2019, 6:38pm UTC](https://forum.crystal-lang.org/t/how-to-know-the-concrete-type-of-generics/1452 "2019-12-06T18:38:38Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jacob](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/jacob/32/615_2.png) [@jacob](https://forum.crystal-lang.org/u/jacob)\
**Post date:** [December 6, 2019, 6:38pm UTC](https://forum.crystal-lang.org/t/how-to-know-the-concrete-type-of-generics/1452/1 "2019-12-06T18:38:38Z")

</div>

I want to write a method for collection types, filter out all nil and cast down the type.

```auto
class Array(T)
  def purge
     self.compact.map(&.as(T))
  end
end

a = [nil, 1, 2, nil] of Int32 | Nil
a = a.purge
p typeof(a[0])

```

After purge, Array(Int32 | nil) will be Array(Int32), but I don’t know how to make the code work.  
Since T could be a compound type Int32 | nil, the code do nothing.

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:** [December 6, 2019, 6:54pm UTC](https://forum.crystal-lang.org/t/how-to-know-the-concrete-type-of-generics/1452/2 "2019-12-06T18:54:06Z")

</div>

Hi!

Sorry, I don’t understand what you mean. Could you provide some code that shows what value/type you get, and what value/type you expect to get?

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [December 6, 2019, 6:58pm UTC](https://forum.crystal-lang.org/t/how-to-know-the-concrete-type-of-generics/1452/3 "2019-12-06T18:58:34Z")

</div>

> [@jacob](#):
>
> After purge, Array(Int32 | nil) will be Array(Int32)

I think you would have to return a new array that doesn’t include the `Nil` type. This can already be done by using `compact` as you have.

[https://play.crystal-lang.org/#/r/85h2](https://play.crystal-lang.org/#/r/85h2)

```auto
a = [nil, 1, 2, nil] of Int32 | Nil
 
p typeof(a[0]) # => (Int32 | Nil)
p typeof(a) # => Array(Int32 | Nil)
 
a = a.compact
 
p typeof(a[0]) # => Int32
p typeof(a) # => Array(Int32)

```

---

<div class="post-metadata">

**Author:** ![RespiteSage](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/respitesage/32/793_2.png) [@RespiteSage](https://forum.crystal-lang.org/u/RespiteSage)\
**Post date:** [December 6, 2019, 7:12pm UTC](https://forum.crystal-lang.org/t/how-to-know-the-concrete-type-of-generics/1452/4 "2019-12-06T19:12:41Z")

</div>

Note that you must use `#compact` (and not `#compact!`) and reassign the variable. This slight modification to the above code will _not_ work:

```crystal
a = [nil, 1, 2, nil] of Int32 | Nil

p typeof(a[0]) # => (Int32 | Nil)
p typeof(a) # => Array(Int32 | Nil)

a.compact! # <= THIS IS DIFFERENT

p typeof(a[0]) # => (Int32 | Nil)
p typeof(a) # => Array(Int32 | Nil)

```

[https://play.crystal-lang.org/#/r/85hn](https://play.crystal-lang.org/#/r/85hn)

---

<div class="post-metadata">

**Author:** ![jacob](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/jacob/32/615_2.png) [@jacob](https://forum.crystal-lang.org/u/jacob)\
**Post date:** [December 7, 2019, 7:26am UTC](https://forum.crystal-lang.org/t/how-to-know-the-concrete-type-of-generics/1452/5 "2019-12-07T07:26:13Z")

</div>

That’s exactly what I have tried, compact! So I thought compact will be same.

Thanks.
