You can use separate OpCode types:
data Opcode0 = NOP data Opcode1 = INC data Opcode2 = ADD | MUL data Cmd = Cmd0 Opcode0 | Cmd1 Opcode1 Arg | Cmd2 Opcode2 Arg Arg
Now sometimes you can consider all Opcodes as one type, say, to put them on a list. To do this, you can use the type class for Opcode types and use existential types :
class OpcodeCl a where --empty classes seem to be allowed (in GHC at least) instance OpcodeCl Opcode0 where instance OpcodeCl Opcode1 where instance OpcodeCl Opcode2 where data Opcode = forall a . (OpcodeCl a) => Op { unOp :: a }
I suspect you cannot do anything with OpCode here, since the OpcodeCl class has no methods. You can add useful methods to OpcodeCl that convert to or from Int s, for example.
source share