给定是否可能
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
实例。