My examples here are using GHCI 8.4.4 with a prompt, "λ: "
.
I think deriving from Enum
makes the most sense here, as the most fundamental types in Haskell also derive from Enum
(tuples, characters, integers, etc...), and it has builtin methods of getting values into and from the enum.
First, create a data type deriving Enum
(and Show
so you can view the value in the REPL and Eq
to enable ..
range completion):
λ: data MyDataType = Foo | Bar | Baz deriving (Enum, Show, Eq)
λ: [Foo ..]
[Foo,Bar,Baz]
Enums define a method, fromEnum
, which you can use to get the values as requested in the question (0
, 1
, and 2
).
Usage:
λ: map fromEnum [Foo ..]
[0,1,2]
It is a simple matter to define a function giving an arbitrary value (such as powers of two using the integer power operator, ^
):
λ: value e = 2 ^ (fromEnum e)
Usage:
λ: map value [Foo ..]
[1,2,4]
Another answer says:
The deriving Enum
solution is great, but it won't work if you want to have an arbitrary mapping to numbers.
Well, let's see about that (use :set +m
to enable multiline input in GHCI, if you haven't already):
arbitrary e = case e of
Foo -> 10
Bar -> 200
Baz -> 3000
Usage:
λ: map arbitrary [Foo ..]
[10,200,3000]
We just demonstrated that it does indeed work, but I would prefer to calculate it from the fromEnum
as we did with value
, if we do not want values increasing by 1 from 0.
deriving Enum
? It is magical! – Northeastwardsdata SomeEnum = ValueA | Reserved1 | Reserved2 | ValueB | Reserved3 | ValueC
– Xuthusderiving Enum
, but then write your own version of thetoEnum'
andfromEnum'
which calltoEnum
andfromEnum
and then do the 2^x conversion. Whether this is any better, I don't know. – HawaiiEnum
instance, at all. If you need powers of two, maybe you want to use theenumset
package for defining flag sets? – Bettyebettzel