当前位置: 首页 > 知识库问答 >
问题:

使用模板Haskell获取关联的类型同义词

吴伟志
2023-03-14

模板Haskell能找出类型类中声明的关联类型同义词的名称和/或声明吗?我希望Reify能做我想做的事情,但它似乎没有提供所有必要的信息。它用于获取函数类型签名:

% ghci
GHCi, version 7.8.3: http://www.haskell.org/ghc/  :? for help
...
Prelude> -- I'll be inserting line breaks and whitespace for clarity
Prelude> -- in all GHCi output.
Prelude> :set -XTemplateHaskell 
Prelude> import Language.Haskell.TH
Prelude Language.Haskell.TH> class C a where f :: a -> Int
Prelude Language.Haskell.TH> putStrLn $(stringE . show =<< reify ''C)
ClassI (ClassD [] Ghci1.C [PlainTV a_1627398388] []
               [SigD Ghci1.f
                     (ForallT [PlainTV a_1627398388]
                              [ClassP Ghci1.C [VarT a_1627398388]]
                              (AppT (AppT ArrowT (VarT a_1627398388))
                                    (ConT GHC.Types.Int)))])
       []

但是,将关联的类型同义词添加到类中不会导致输出中的更改(直到重命名):

Prelude Language.Haskell.TH> :set -XTypeFamilies 
Prelude Language.Haskell.TH> class C' a where type F a :: * ; f' :: a -> Int
Prelude Language.Haskell.TH> putStrLn $(stringE . show =<< reify ''C')
ClassI (ClassD [] Ghci3.C' [PlainTV a_1627405973] []
               [SigD Ghci3.f'
                     (ForallT [PlainTV a_1627405973]
                              [ClassP Ghci3.C' [VarT a_1627405973]]
                              (AppT (AppT ArrowT (VarT a_1627405973))
                                    (ConT GHC.Types.Int)))])
       []
Prelude Language.Haskell.TH> putStrLn $(stringE . show =<< reify ''F)
FamilyI (FamilyD TypeFam
                 Ghci3.F
                 [PlainTV a_1627405973]
                 (Just StarT))
        []
Prelude Language.Haskell.TH> instance C' [a] where type F [a] = a ; f' = length
Prelude Language.Haskell.TH> f' "Haskell"
7
Prelude Language.Haskell.TH> 42 :: F [Integer]
42
Prelude Language.Haskell.TH> putStrLn $(stringE . show =<< reify ''C')
ClassI (ClassD [] Ghci3.C' [PlainTV a_1627405973] []
               [SigD Ghci3.f'
                     (ForallT [PlainTV a_1627405973]
                              [ClassP Ghci3.C' [VarT a_1627405973]]
                              (AppT (AppT ArrowT (VarT a_1627405973))
                                    (ConT GHC.Types.Int)))])
       [InstanceD []
                  (AppT (ConT Ghci3.C')
                        (AppT ListT (VarT a_1627406161)))
                  []]

共有1个答案

南宫鸿晖
2023-03-14

它没有实现,因为没有人要求它。

奇怪的是TH使用它自己的AST,它不遵循内部编译器的AST。因此,任何新特性(例如相关的类型族)都不能通过TH自动获得。有些人必须开一张票并实施它。

有关引用:internalReifyClass函数忽略关联的类型族(它是ClassExtraBigSig返回的元组的第5个元素,请参见ClassAtitem的定义。)

补充:它现在已经实现(不需要API更改),可能会在下一个GHC版本中提供。

 类似资料:
  • 我有一个函数,它返回一个动态绑定的-本质上,。当然,实际函数要复杂得多,足以让我为它编写测试,最好是清晰的测试。但是以下: 将始终失败,因为将解析为而不是ConT MyType。 是否有一种很好的方法将类型转换为完全限定的类型,或者检查和是否相同(在当前上下文中)?

  • 通过预先确定好模型之间的关系,在业务开发中,使用非常简便的写法,就可以实现复杂的涉及多表数据增删改查。 这一切都是模型底层实现帮你在处理,在 imi 中,模型的关联关系都使用注解来定义。 注解 这里列出定义模型关联关系所需的注解,所有关联模型的注解,命名空间为Imi\Model\Annotation\Relation @OneToOne 一对一关系声明 用法: @OneToOne("模型类名")

  • 使用“关联类型”可以增强代码的可读性,其方式是移动内部类型到一个 trait 作为output(输出)类型。这个 trait 的定义的语法如下: // `A` 和 `B` 在 trait 里面通过`type` 关键字来定义。 // (注意:此处的 `type` 不同于用作别名时的 `type`)。 trait Contains { type A; type B; // 通常

  • 当使用创建类型同义词时,GHC/GHCI在显式使用时将使用它而不是原始类型,但绝不会尝试从推断的类型向后工作到匹配的同义词。获取一个类型的最“抽象”的同义词对于学习复杂的应用程序和库非常方便,这些应用程序和库定义了单子堆栈的同义词,也可能定义了同义词的同义词。

  • 关联类型 定义一个协议时, 有时在协议定义里声明一个或多个关联类型是很有用的. 关联类型给协议中用到的类型一个占位符名称. 直到采纳协议时, 才指定用于该关联类型的实际类型. 关联类型通过associatedtype关键字指定. 关联类型的应用 protocol Container { associatedtype ItemType mutating func append(_ i

  • 我正在为实体对象上的延迟加载集合执行此操作: 我想返回一个实体对象,其中加载了多个延迟加载的集合,我可以这样做吗(传入一个列表并为单个条件设置多个关联?):