0

I got the following data type:

data Icon = IconCircle | IconSquare | IconStar

I need an array of all possible Icons?:

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.

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Hint: these imports are necessary: ``` import Data.Functor ((<$>)) import Data.Tuple import Data.Unfoldable (unfoldr) import Data.Bounded.Generic (genericBottom) import Data.Enum.Generic (genericSucc) import Data.Generic.Rep (class Generic) ```
1

Fyodor's answer is incorrect unfortunately. The last value is omitted because it is mapped on it's non existing successor (i.e. Nothing).

A working alternative might be:

allPossible :: Array Icon
allPossible = unfoldr (\b -> b >>= next) $ Just genericBottom
  where
    next a = Just $ Tuple a $ genericSucc a

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.