我有一个总和类型的记录来表示所有内存表,因为我将通过网络发送它们。我有一个二进制协议,需要首先传递标头中的序数值(fromEnum),以确定数据与哪个表相关联。问题是总和类型需要从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
答案 0 :(得分:2)
如果您只想枚举构造函数,可以使用Data.Data模块,如下所示:
{-# 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
。