I have a sum type representing arithmetic operators:
data Operator = Add | Substract | Multiply | Divide
and I'm trying to write a parser for it. For that, I would need an exhaustive list of all the operators.
In Haskell I would use deriving (Enum, Bounded)
like suggested in the following StackOverflow question: Getting a list of all possible data type values in Haskell
Unfortunately, there doesn't seem to be such a mechanism in Idris as suggested by Issue #19. There is some ongoing work by David Christiansen on the question so hopefully the situation will improve in the future : david-christiansen/derive-all-the-instances
Coming from Scala, I am used to listing the elements manually, so I pretty naturally came up with the following:
Operators : Vect 4 Operator
Operators = [Add, Substract, Multiply, Divide]
To make sure that Operators
contains all the elements, I added the following proof:
total
opInOps : Elem op Operators
opInOps {op = Add} = Here
opInOps {op = Substract} = There Here
opInOps {op = Multiply} = There (There Here)
opInOps {op = Divide} = There (There (There Here))
so that if I add an element to Operator
without adding it to Operators
, the totality checker complains:
Parsers.opInOps is not total as there are missing cases
It does the job but it is a lot of boilerplate. Did I miss something? Is there a better way of doing it?
Enum
interface forOperator
manually. – Anton TrunovfromNat
should behave for example. – bloueratfromNat Z = Add fromNat (S Z) = Subtract fromNat (S (S Z)) = Multiply fromNat (S (S (S _))) = Divide
might work for you. – Anton TrunovEnum
does seem more idiomatic but then I have to give up exhaustiveness which is a bit of a shame – bloueratop
, there is ak : Nat
, such thatfromNat k = op
– Kim Stebel