I got the following data type:
data Icon = IconCircle | IconSquare | IconStar
I need an array of all possible Icon
s?:
allPossible :: Array Icon
allPossible = [IconCircle, IconSquare, IconStar]
Is there a shortcut to create this array? e.g when there are 20 (or a lot more) possible Icons?
When not:
Is it possible to create a type for allPossible
that forces all possible Icons to be included?
My goal is to force that this array is never incomplete.
Yes, there is!
You can derive Generic
and then use GenericEnum
in combination with GenericBottom
to enumerate all constructors:
data Icon = IconCircle | IconSquare | IconStar
derive instance Generic Icon _
allPossible :: Array Icon
allPossible = unfoldr (\a -> Tuple a <$> genericSucc a) genericBottom
And you can even make this completely generic, so it would work for any type, not just for Icon
:
allPossible :: forall a rep.
Generic a rep =>
GenericEnum rep =>
GenericBottom rep =>
Array a
allPossible = unfoldr (\a -> Tuple a <$> genericSucc a) genericBottom
Of course, this will only work for types that are actually enums - i.e. every constructor is either parameterless or its parameters have instances of Enum
. If the type is not an enum in this sense, this will fail to compile, complaining that it's impossible to construct a GenericEnum
instance.