使用简单和类型的所有值构造n元乘积 [英] Constructing a n-ary product with all the values of a simple sum type
问题描述
我正在使用 generics-sop 库.我要编写以下类型的值:
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)
也就是说,对于其构造函数没有任何参数的求和类型( NP
),其中
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.
例如,对于类型
{-# LANGUAGE DeriveGeneric #-}
import qualified GHC.Generics as GHC
import Generics.SOP
data Foo = Bar
| Baz
deriving (GHC.Generic)
instance Generic Foo
我想生产n元产品
K Bar :* K Baz :* Nil
我相信解决方案将涉及转换带有每个构造函数的通用表示形式的n元乘积,所以我这样写:
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)) _
使用 liftA_NP
和
Using liftA_NP
and mapKK
. But I'm not sure how to produce the generic representations themselves.
推荐答案
您可以使用现有的 injections
或 apInjs *
函数.
You can use the existing injections
or apInjs*
functions.
使用
apInjs'_NP :: SListI xs => NP f xs -> NP (K (NS f xs)) xs
您必须提供函数自变量的乘积一般情况下,每个组件都将应用于以下其中一个组件基础数据类型的构造函数.
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!
values :: forall r . IsEnumType r => NP (K r) (Code r)
values =
map_NP
(mapKK (to . SOP))
(apInjs'_NP
(cpure_NP (Proxy @((~) '[])) Nil)
)
这篇关于使用简单和类型的所有值构造n元乘积的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!