在Haskell中枚举GADT

时间:2013-04-24 17:17:25

标签: haskell combinatorics gadt

请告诉我,Enum类的Haskell派生机制是否有任何扩展?我的意思是除了“nullary constructors”之外还有很多合理的情况。关于这个主题是否有任何作品?

1 个答案:

答案 0 :(得分:4)

你真的需要GADT吗?或者你只是想将限制解除为只有nullary构造函数的普通枚举类型?如果是后者,则有选择权。一种是使用GHC的Generic机制以及适当通用的枚举类的实现。这可以在generic-deriving包中找到。这是一个例子:

{-# LANGUAGE DeriveGeneric #-}
import Generics.Deriving

data Tree a = Leaf a | Node (Tree a) (Tree a)
  deriving (Show, Generic)

instance GEnum Bool
instance GEnum a => GEnum (Tree a)

test :: [Tree Bool]
test = take 10 genum

现在,test是以下列表:

[ Leaf False
, Node (Leaf False) (Leaf False)
, Leaf True
, Node (Leaf False) (Node (Leaf False) (Leaf False))
, Node (Node (Leaf False) (Leaf False)) (Leaf False)
, Node (Leaf False) (Leaf True)
, Node (Node (Leaf False) (Leaf False)) (Node (Leaf False) (Leaf False))
, Node (Leaf True) (Leaf False),Node (Leaf False) (Node (Leaf False) (Node (Leaf False) (Leaf False)))
, Node (Node (Leaf False) (Leaf False)) (Leaf True)
]

genum的此实现使用对角化来合并产品。这可以保证每个值实际出现在列表中的某个位置,但可能会依次导致令人惊讶的顺序。