价值约束

voi*_*ard 6 haskell

假设我们有以下数据类型:

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
Run Code Online (Sandbox Code Playgroud)

我们的想法是使用Opcode类型生成顺序操作码编号.有没有办法为Cmd值指定约束,比如说:Cmd0只有NOP操作码,Cmd1只有INC,Cmd2只有ADD或MUL值.我试图使用GATD,但它们按类型而不是值进行操作.

或者反之亦然有没有办法为Cmd的每个值生成一个连续的操作码,而无需手动或不使用TH为每个值声明fromEnum方法?

Pra*_*eek 8

您可以使用单独的OpCode类型:

data Opcode0 = NOP
data Opcode1 = INC
data Opcode2 = ADD | MUL

data Cmd = Cmd0 Opcode0 | Cmd1 Opcode1 Arg | Cmd2 Opcode2 Arg Arg
Run Code Online (Sandbox Code Playgroud)

现在有时您可能希望将所有操作码视为单一类型,比如将它们放在列表中.为此,您可以为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 }
Run Code Online (Sandbox Code Playgroud)

我怀疑你不能在Opcode这里做任何事情,因为班级OpcodeCl没有方法.例如,您可以添加有用的方法OpcodeCl,这些方法可以转换为Ints 或从s 转换.

  • @leftaroundabout它与ghc无关,它是Haskell规范的一部分. (3认同)