假设我们有以下数据类型:
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
我们的想法是使用Opcode类型生成顺序操作码编号.有没有办法为Cmd值指定约束,比如说:Cmd0只有NOP操作码,Cmd1只有INC,Cmd2只有ADD或MUL值.我试图使用GATD,但它们按类型而不是值进行操作.
或者反之亦然有没有办法为Cmd的每个值生成一个连续的操作码,而无需手动或不使用TH为每个值声明fromEnum方法?
您可以使用单独的OpCode
类型:
data Opcode0 = NOP data Opcode1 = INC data Opcode2 = ADD | MUL data Cmd = Cmd0 Opcode0 | Cmd1 Opcode1 Arg | Cmd2 Opcode2 Arg Arg
现在有时您可能希望将所有操作码视为单一类型,比如将它们放在列表中.为此,您可以为Opcode类型使用类型类并使用存在类型:
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 }
我怀疑你不能在Opcode
这里做任何事情,因为班级OpcodeCl
没有方法.例如,您可以添加有用的方法OpcodeCl
,这些方法可以转换为Int
s 或从s 转换.