Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Value constraints

Tags:

haskell

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 ?

like image 609
voidlizard Avatar asked Dec 04 '11 09:12

voidlizard


People also ask

What are value constraints?

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.

What is a constraint in database?

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.


1 Answers

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 Ints, for example.

like image 174
Prateek Avatar answered Sep 22 '22 12:09

Prateek