派生Haskell中记录的总和类型的枚举

派生Haskell中记录的总和类型的枚举,haskell,Haskell,我有一个总和类型的记录来表示所有内存中的表,因为我将通过网络发送它们。我有一个二进制协议,需要首先在头中传递序数值(fromnum),以确定数据与哪个表关联。问题是sum类型需要从Enum派生,但它不想这样做 data Table = MarketData {bid::[Float], ask::[Float]} | Trade {price::[Float], qty::[Float]} deriving Enum main :: IO () main = do

我有一个总和类型的记录来表示所有内存中的表,因为我将通过网络发送它们。我有一个二进制协议,需要首先在头中传递序数值(fromnum),以确定数据与哪个表关联。问题是sum类型需要从Enum派生,但它不想这样做

data Table = MarketData {bid::[Float], ask::[Float]}
     | Trade {price::[Float], qty::[Float]} 
        deriving Enum

main :: IO ()
main = do
    print $ fromEnum Trade
这是编译错误

Can't make a derived instance of `Enum Table':
  `Table' must be an enumeration type
  (an enumeration consists of one or more nullary, non-GADT constructors)
In the data declaration for `Table'
我有没有想过如何做到这一点,而不必编写这样的样板文件:

ordinalVal :: Table -> Int
ordinalVal tbl = case tbl of
      MarketData{bid=_, ask=_} -> 0
    | Trade{price=_, qty=_} -> 1

如果您只想枚举构造函数,您可以使用模块,如下所示:

{-# LANGUAGE DeriveDataTypeable #-}
import Data.Data

data T a b = C1 a b | C2 deriving (Typeable, Data)

main = print $ constrIndex $ toConstr x
  where
    x :: T Int Int
    x = C1 1 1  -- will print 1
    -- x = C2  -- will print 2

如果您不想继续使用
Typebale
Data
类型类,也可以像您建议的那样,简单地编写一个函数
Table->Int

我需要记录语法,因为字段访问方法在我的代码中使用。@jap
data T a b=C1 a b | C2
只是一个例子;不管怎样,您都应该能够继续使用记录。(请注意,混合记录和求和类型的效果不是很好;它使部分记录标签和访问器成为可能。)简化样板的小贴士:当模式匹配记录时,不需要列出未使用的字段。所以你可以只使用
MarketData{}->0
.Thx或jan!那很有帮助