1

我有一个可扩展的乙烯基/复合记录(类似于 HList、Frames...),我想生成键/值的元组,例如

tuplify '[String :-> Whatevs, ...] :: [(String, String)]

这出乎意料地难。原主旨

解决方案要点,感谢下面的 Alec

type FA = "a" :-> String
type FB = "b" :-> Int
type AB = '[FA, FB]

ab :: Rec Identity AB
ab = "A" :*: 1 :*: RNil

tuplify :: (Show a) => Rec Identity '[a] -> [(String, String)]
tuplify = recordToList . rmap undefined -- ??????
-- tuplify ab = [("a", "A"), ("b", "1")]

如果您想尝试一下我到目前为止所做的事情,请查看gist,它有经过深思熟虑的示例和我看到的错误:

这是 Composite ( reifyDicts) 中用于重新编译的硬件:

乙烯基( reifyConstraints) 也是如此:

AFAICT,问题在于rmap

rmap :: (forall x. f x -> g x) -> Rec f rs -> Rec g rs

映射的 fn 已定义forall x,但 mytuplify受到约束,我认为具体化应该将约束移动到类型中(这就是Dicts 的用途),但是,唉,到目前为止还没有运气。

4

1 回答 1

2

我无法composite在我的全局 Stack 设置上安装相关的东西,但以下内容应该仍然有效(我只是复制粘贴了相关定义)。也就是说,我认为基于类型的简单类型类调度在这里更简单(因为约束很重要)。启用所有正确的扩展 [1],您只需要:

class Tuplify a where
  tuplify :: a -> [(String, String)]

instance Tuplify (Rec Identity '[]) where
  tuplify RNil = []

instance (Show t, KnownSymbol s, Tuplify (Rec Identity rs)) =>
           Tuplify (Rec Identity (s :-> t ': rs)) where
  tuplify (v :*: rs) = (symbolVal (Proxy :: Proxy s), show v) : tuplify rs

然后,在 GHCi 中:

ghci> tuplify ab
[("a","\"A\""),("b","1")]

如果您真的想尝试具体化约束方法,则必须首先为您想要的特定约束声明一个类型类和实例:

class ShowField a where 
  showField :: a -> (String, String)                                                                                

instance (KnownSymbol s, Show a) => ShowField (Identity (s :-> a)) where
  showField (Identity (Val v)) = (symbolVal (Proxy :: Proxy s), show v)

然后它变得更易于使用reifyConstraintsand rmap

tuplify' :: RecAll Identity rs ShowField => Rec Identity rs -> [(String, String)]
tuplify' xs = recordToList
            . rmap (\(Vinyl.Compose (Dict x)) -> Vinyl.Const $ showField x)
            $ reifyConstraint (Proxy :: Proxy ShowField) xs

我想类似reifyDicts的事情可能与.ValuesAllHaveAllHaveShowField


[1] extensions needed for first example

{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE FlexibleContexts    #-}
{-# LANGUAGE FlexibleInstances   #-}
{-# LANGUAGE GADTs               #-}
{-# LANGUAGE RankNTypes          #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies        #-}
{-# LANGUAGE TypeOperators       #-}
于 2017-08-03T06:06:13.470 回答