gpt4 book ai didi

haskell - 从类型级别列表创建值列表

转载 作者:行者123 更新时间:2023-12-05 00:15:35 26 4
gpt4 key购买 nike

我有一个这样的类型级别列表

data TList (ixs :: [*]) (f :: * -> *) where
TNil :: TList '[] f
(:-:) :: f ix -> TList ixs f -> TList (ix ': ixs) f

我正在尝试使用现有的 TList 生成新的 TList。
这个想法是有一个功能
genTList :: TList ixs f -> t -> TList ixs g

其中“t”是一些能够构造“g x”类型值的函数,其中“x”是列表“ixs”中的一种类型。

所以给定
data Foo x

和(某种)
generate :: forall x . Bar x

我可以得到这样的东西
genTList (Foo Int :-: Foo String) generate = Bar :-: Bar

所以基本上对于类型列表中的每个项目 'x' 我想要一个类型 'Bar x'
并且还用无参数构造函数构造它的值,因为我知道
'Bar x' 没有构造函数参数。

我试图实现一些东西( https://gist.github.com/lolepezy/30820595afd9217083c5ca629e350b55 ),但它不会(合理地)进行类型检查。

那么我应该如何解决这个问题呢?

最佳答案

你定义

class TListGen ixs (g :: * -> *) where
genTList :: Proxy ixs -> g ix -> TList ixs g

但这意味着函数的调用者可以选择用什么来实例化所有类型变量,所以特别是如何实例化 ix .

例如,
genTList (Proxy :: Proxy '[Int, String]) (Just False)

将是此函数的类型正确调用,选择 g成为 Maybeix成为 Bool .但这不可能是正确的。我们需要传入一些足够多态的东西,它至少适用于出现在类型级列表中的所有元素,或者甚至更好,适用于任何可能的 ix 选择。 .这是 2 级多态类型所实现的:
class TListGen ixs (g :: * -> *) where
genTList :: Proxy ixs -> (forall ix . g ix) -> TList ixs g

这需要 RankNTypes语言扩展。

现在调用者只能传递参数类型为 g 的多态函数。 .所以路过 Just False将不再有效,但会通过 Nothing没问题。

case 的定义原则上是可以的,但你实际上可以删除 OVERLAPS pragma 甚至代理参数,因为没有重叠,而 ixs可以从结果类型推断出来,因为它作为 TList 的参数出现。数据类型:
class TListGen ixs (g :: * -> *) where
genTList :: (forall ix . g ix) -> TList ixs g

instance TListGen '[] g where
genTList _ = TNil

instance TListGen ixs g => TListGen (ix ': ixs) g where
genTList g = g :-: genTList g

现在我们可以尝试使用它:
GHCi> genTList Nothing :: TList '[ Int, String ] Maybe

不幸的是,这会导致错误,因为没有 Show实例:
• No instance for (Show (TList '[Int, String] Maybe))
arising from a use of ‘print’
• In a stmt of an interactive GHCi command: print it

定义 Show TList 的实例是可能的,但有点棘手。

我不确定这是否主要是一个练习,但如果您只需要重用代码就可以了,那么所有这些都可以在 generics-sop 中找到。包裹。

您的 TList被称为 NP (参数按翻转顺序),以及您的 genTList被称为 pure_NP ,所以你可以写
GHCi> import Generics.SOP.NP
GHCi> pure_NP Nothing :: NP Maybe '[ Int, String ]
Nothing :* (Nothing :* Nil)

关于haskell - 从类型级别列表创建值列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44244696/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com