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

Type parameter variance of enum #28

Open
wants to merge 3 commits into
base: master
from

Conversation

Projects
None yet
3 participants
@shohei909
Copy link

shohei909 commented Sep 24, 2017

This proposes new variance rule for enum.

Rendered version

@Simn

This comment has been minimized.

Copy link
Member

Simn commented Sep 25, 2017

Interesting... but I wonder, does this actually solve any problem? I can see your reasoning from a typing theory point of view, but I'm not convinced that the additional complexity actually comes with any advantage.

@skial skial referenced this pull request Sep 25, 2017

Closed

Haxe Roundup 401 #434

@shohei909

This comment has been minimized.

Copy link

shohei909 commented Sep 25, 2017

Of course, this has advantages. I added an actual example.

@Simn

This comment has been minimized.

Copy link
Member

Simn commented Sep 3, 2018

To clarify, this is the failing case:

import haxe.ds.Option;

class Main {
	static public function main() {
		var optionFloat:Option<Float>;
		var optionInt = Option.Some(1);
		optionFloat = optionInt;
	}
}

Your direct assignment works already due to top-down inference.

And yes I can see the point here. Given that enum arguments are read-only, covariance could be allowed.

@ncannasse: Any opinions?

@ncannasse

This comment has been minimized.

Copy link
Member

ncannasse commented Sep 3, 2018

The problem is that type parameters variance depends on the way it's used.
For instance:

enum Option<T> {
    None;
    Some( f : Void -> T );
}

In this case T is contravariant...

@shohei909

This comment has been minimized.

Copy link

shohei909 commented Sep 16, 2018

If you mean this Option1, yes, the Option1.T is contravariant.

enum Option1<T> {
    None;
    Some( f : T -> Void );
}

However, Option1 is different type from Option2:

enum Option2<T> {
    None;
    Some( f : T );
}

Option2.T is covariant without regard to usage.

This is the list of "A is B" relation:

A B
Int Float
Float -> Void Int -> Void
Option1<Float> Option1<Int>
Option1<Int -> Void> Option1<Float -> Void>
Option2<Int> Option2<Float>
Option2<Float -> Void> Option2<Int -> Void>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment