Let's assume we have the following data type:
data Cmd = Cmd0 Opcode | Cmd1 Opcode Arg | Cmd2 OPcode Arg Arg
data Opcode = NOP | INC | ADD | MUL deriving (Enum)
data Arg = W32 Int | W16 Int | W8 Int
The idea is to have an Opcode type that produces sequential opcode numbers. Is there any way to specify a constraints for Cmd values, say: Cmd0 is only has NOP opcode, Cmd1 is only INC, Cmd2 is only ADD or MUL values. I tried to use GATDs, but they operates by types, not values.
Or vise versa is there any way to generate a sequentual opcodes for every value of Cmd without declaring fromEnum method for every value manually or without using TH ?
Value constraints refine a simple type by defining limits on the values which it can represent. It is often useful to be able to constrain the values which an element can take, perhaps to ensure that messages conform to business rules.
Constraints are used to limit the type of data that can go into a table. This ensures the accuracy and reliability of the data in the table. If there is any violation between the constraint and the data action, the action is aborted. Constraints can be column level or table level.
You could 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 might want to treat all the Opcodes as a single type, say to put them in a list. For this purpose you could use a 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 wouldn't be able to do anything with Opcode
here, since the class OpcodeCl
has no methods. You could add useful methods to OpcodeCl
, which convert to or from Int
s, for example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With