I'm working with the generics-sop library. I want to write a value with the following type:
values :: forall r. IsEnumType r => NP (K r) (Code r)
That is, for sum types whose constructors don't have any arguments (IsEnumType
) I want to produce an n-ary product (NP
) which contains the corresponding constructor value at each point.
For example, for the type
{-# LANGUAGE DeriveGeneric #-}
import qualified GHC.Generics as GHC
import Generics.SOP
data Foo = Bar
| Baz
deriving (GHC.Generic)
instance Generic Foo
I want to produce the n-ary product
K Bar :* K Baz :* Nil
I believe the solution will involve transforming an n-ary product carrying generic representations of each constructor, so I wrote this:
values :: forall r. IsEnumType r => NP (K r) (Code r)
values = liftA_NP (mapKK (to . SOP)) _
Using liftA_NP
and mapKK
. But I'm not sure how to produce the generic representations themselves.
You can use the existing
injections
orapInjs*
functions.With
you have to supply a product of function arguments where, in our generic case, each of the components will be applied to one of the constructors of the underlying datatype.
But because we are assuming an enumeration type, none of these constructors have any arguments, and we can supply the empty list of arguments everywhere!