Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Union inconsistency #3687

Closed
TechMagister opened this issue Dec 13, 2016 · 2 comments
Closed

Union inconsistency #3687

TechMagister opened this issue Dec 13, 2016 · 2 comments

Comments

@TechMagister
Copy link

Crystal 0.20.1 [18e7617] (2016-12-05)
OS : Linux

Union are working half as expected in this case :

alias MyType = Int32 | String | Array(MyType)

my_hash = Hash(String, MyType).new

# this is ok, giving [1, 2, 3] is recognized as a MyType
def do_something(t : MyType)
  t.is_a? Array(Int32)			# => true
end

arr = [1,2,3]
do_something arr             # Working
my_hash["a"] = arr           # Compilation error here ??

The Array(Int32) is well recognized as a MyType ( Array(MyType) ) when given as function argument but not when giving it to the hash.

instance variable '@value' of Hash::Entry(String, MyType) must be MyType, not Array(Int32)
@RX14
Copy link
Contributor

RX14 commented Dec 13, 2016

I think we need a well written up answer in a section of the crystal docs about this. Unfortunately I can't find the great answer that I seem to remember @asterite giving about this a while ago.

@asterite
Copy link
Member

Hi,

Maybe it's an inconsistency, but it's the way it works. Type restrictions are different than proper types. For example:

def foo(x : Range(Int, Int))
end

foo 1..10 # Works
p typeof(1..10) # => Range(Int32, Int32)

We are passing Range(Int32, Int32). The restriction says "I accept a Range where both components are ints", and since Int32 < Int, it works.

In the case of the alias, Array(Int32) can be matched against Array(MyType) because MyType can also be Int32... however, it's incorrect to put an Array(Int32) inside an Array(MyType).

Check #1297

I'm closing this. We'll eventually solve this. I think this is one of the points that bring people most confusion... but then again, you should really try to avoid using unions and recursive types if possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants