我正在使用generics-sop库 . 我想写一个具有以下类型的值:
values :: forall r. IsEnumType r => NP (K r) (Code r)
也就是说,对于构造函数没有任何参数(IsEnumType)的sum类型,我想生成一个n-ary乘积(NP),其中contains是每个点的相应构造函数值 .
例如,对于类型
{-# LANGUAGE DeriveGeneric #-}
import qualified GHC.Generics as GHC
import Generics.SOP
data Foo = Bar
| Baz
deriving (GHC.Generic)
instance Generic Foo
我想 生产环境 n-ary产品
K Bar :* K Baz :* Nil
我相信解决方案将涉及转换带有每个构造函数的通用表示的n-ary产品,所以我写了这个:
values :: forall r. IsEnumType r => NP (K r) (Code r)
values = liftA_NP (mapKK (to . SOP)) _
2 回答
您可以使用现有的
injections
或apInjs*
函数 .同
你必须提供函数参数的产品,在我们的通用情况下,每个组件将应用于基础数据类型的一个构造函数 .
但是因为我们假设一个枚举类型,所以这些构造函数都没有任何参数,我们可以在任何地方提供空的参数列表!
也许有一种更简单的方法,但我设法通过使用辅助类型类
POSN
定义values
,它基本上对空类型级列表的类型级列表执行归纳:内部
NP
总是Nil
,因为它们对应于每个构造函数的参数,并且从不存在任何参数 .归纳步骤为列表的其余部分的每个总和“加1”,在头部预先设置为“零” .
使用示例: