使用简单和类型的所有值构造n元乘积 [英] Constructing a n-ary product with all the values of a simple sum type

查看:57
本文介绍了使用简单和类型的所有值构造n元乘积的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 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)

也就是说,对于其构造函数没有任何参数的求和类型(

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆