在Haskell中为Enum类型的记录派生Enum

时间:2014-05-14 17:50:10

标签: haskell

我有一个总和类型的记录来表示所有内存表,因为我将通过网络发送它们。我有一个二进制协议,需要首先传递标头中的序数值(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

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

如果您不想使用TypebaleData类型类,那么您也可以像编写的那样简单地编写一个函数Table -> Int