COMMUNITY

Non-exhaustive abstract enums

Imagine the following scenario

@:enum abstract DirectionFlags(Int) to Int {
	var LEFT = 0x0001;
	var RIGHT = 0x0010;
	var UP = 0x0100;
	var DOWN = 0x1000;
	var ALL = 0x1111;
	var NONE = 0x1111;
}

An exhaustive switch is expected to check all 6 values above, but there’s actually 16 values, and other flag types can have many more. The exhaustive error: “Unmatched patterns: ALL | NONE” is a little deceptive. Is there a way to make it so that:
A. exhaustive checks aren’t needed for this type. any combo of cases will not cause a compile error.
B. a default case is always needed in switches of this type
C. certain cases aren’t needed. For this abstract, ANY and NONE would be optional
D. Switches of this type are treated as the underlying type. i.e. Int, here.

You could just define it as static constants in an abstract (not enum)

Like so

abstract DirectionFlags2(Int) to Int {
	public inline static var LEFT = wrap(0x0001);
	public inline static var RIGHT = wrap(0x0010);
	public inline static var UP = wrap(0x0100);
	public inline static var DOWN = wrap(0x1000);
	public inline static var ALL = wrap(0x1111);
	public inline static var NONE = wrap(0x1111);

	static inline function wrap(v:Int):DirectionFlags2 {
		return cast v;
	}
}

The problem with this is that you can’t just say LEFT, it needs to be DirectionFlags2.LEFT, which is a bit annoying

You are right, although you have a few options.

You could bring the static fields into the top scope by using wildcard import:

import my.pack.DirectionFlags.*;

Or you could define public module level fields in your DirectionFlags module which would be imported along side the DirectionFlags abstract.

See this try haxe:

(edit I had linked to the wrong try haxe version)

I could imagine this being a decent solution for certain situations, but for my case, it’s probably better confusing exhaustive switch errors instead of requiring imports or module defs:/

thanks for the sharing!