Haskell 动态获取类型的数据构造函数列表

Haskell 动态获取类型的数据构造函数列表,haskell,reflection,types,Haskell,Reflection,Types,我的数据类型如下: data ABCS=A Int | B Int |…|Z Int派生(数据,可键入) 在测试中,我想动态提取所有构造函数,从每个构造函数中生成一个实例,然后运行测试 我一直在浏览数据.Typeable和数据.Data,但我还没有看到/理解如何从类型(ABC)开始准确地执行此操作 非常感谢您的帮助。如果您可以使用数据。Data,它适用于此用例,但由于Int参数的原因,它有点笨重 {-# LANGUAGE ScopedTypeVariables #-} import Data.D

我的数据类型如下:

data ABCS=A Int | B Int |…|Z Int派生(数据,可键入)

在测试中,我想动态提取所有构造函数,从每个构造函数中生成一个实例,然后运行测试

我一直在浏览
数据.Typeable
数据.Data
,但我还没有看到/理解如何从类型(ABC)开始准确地执行此操作


非常感谢您的帮助。

如果您可以使用
数据。Data
,它适用于此用例,但由于
Int
参数的原因,它有点笨重

{-# LANGUAGE ScopedTypeVariables #-}
import Data.Data
import Data.Typeable

allCtors :: forall a. Data a => [Int -> a]
allCtors = map observeCtor $ dataTypeConstrs $ dataTypeOf (undefined :: a)
  where
    observeCtor :: Constr -> Int -> a
    observeCtor c i = fromJust $ fromConstrM (cast i) c
然后我们有

λ data ABC = A Int | B Int | C Int deriving (Show, Data, Typeable)
data ABC = A Int | B Int | C Int
λ map ($ 2) allCtors :: [ABC]
[A 2,B 2,C 2]
如果您不想使用
Data.Data
,您可以使用
GHC.Generics
-XDefaultSignatures


FWIW,如果你能重构ABC,使A、B、C标记成为它们自己的类型,你就不必处理这些问题了

data ABCTagged = ABCTagged ABC Int deriving Show

data ABC = A | B | C deriving (Show, Eq, Ord, Enum. Bounded)

。。。然后只需使用
enumfromminbound::[ABC]
即可获得整个列表。容易的!但不确定这对您来说有多可行。

已经做了您想要做的事情(没有诉诸
Data.Data
)?否则,您希望提供给构造函数的参数是什么?基本上,我希望将数字列表与构造函数列表连接起来。但是我想动态获取构造函数列表。
arbitral
在这种情况下对我没有帮助。我不希望随机生成数据。我想为每个数据实例测试一个条件。您可能还想查看
smallcheck
用于生成测试用例的任何内容。与quickcheck不同,它是为详尽的测试而设计的。@dfeur我认为答案可能是实际使用smallcheck!谢谢你的推荐。数据类型不是我的实际数据类型。这是我能做的最简单的例子,可以表达我正在努力实现的目标。因此,标记的示例对我不起作用。但是谢谢你的建议。为了我自己的理解,我正在一块一块地分解你的答案,当我执行这个
fromcontrm时(只有10::也许Int)ctor
I get
无法将类型“d”与“Int”匹配。“d”是一个刚性类型变量,由上下文所需的类型绑定:forall d。数据d=>Maybe d at:52:1预期类型:Maybe d实际类型:Maybe Int
在这种情况下,ctorA确实持有一个有效的
a
构造函数
show ctorA
->“a”好的,我已经部分弄清楚了:
让c=cast 10::forall d。数据d=>可能是d
然后从constrm c ctorA得到
但是我得到的
只是()
你的想法是对的<代码>演员阵容10::全d。数据d=>可能d
几乎可以工作,但是
10
的类型将默认为
Integer
,因此当我们尝试将其转换为
Int
时,我们会遇到问题。问题#2是,当您从constrm调用
时,您需要更具体地说明类型,否则您将得到所有d的
。数据d=>可能是d
,GHCi足够好,可以为您默认为
d~()
。因此,完整的咒语应该是
fromcontrm(cast(10::Int))ctorA::也许是ABC