是否获取包含所有数据类型可能值的数组



给定是否可能

data Letter = A | B | C | ... | Z

自动获取一个包含所有可能值的数组:

[A, B, C, ..., Z]

您可以使用自动派生的Generic类型类:

data Letter = ...
derive instance Generic Letter _

请注意derive行末尾的下划线:Generic类型类采用两种类型——(1(您正在描述的数据类型和(2(它的泛型描述,但后者将由编译器自动为您提供。这就是下划线的意思。

然后,您可以通过索引枚举所有元素,使用genericBottom/genericTop获取索引范围,genericFromEnum/genericToEnum转换为整数。

一个问题是genericToEnum返回一个Maybe,因为严格来说,不是每个整数都可以转换为枚举值,但在这种情况下,你知道所有的数字都是有效的,因为你首先是通过genericFromEnum获得的,所以你可以只使用mapMaybe而不是常规映射:

allElements ::
forall a rep.
Generic a rep =>
GenericBoundedEnum rep =>
GenericTop rep =>
GenericBottom rep =>
Array a
allElements = mapMaybe genericToEnum (idxFrom..idxTo)
where
idxFrom = genericFromEnum (genericBottom :: a)
idxTo = genericFromEnum (genericTop :: a)

用法:

allLetters :: Array Letter
allLetters = allElements

注意,allElements函数足够通用,可以处理任何类型,前提是(1(它的所有构造函数都是无参数的,(2(它有一个Generic实例。

最新更新