模板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)))])
[] …Run Code Online (Sandbox Code Playgroud) haskell type-families reify template-haskell associated-types
似乎模板Haskell经常被Haskell社区视为一种不幸的便利.我很难准确地说出我在这方面所观察到的内容,但请考虑这几个例子
我已经看过各种博客文章,其中人们使用模板Haskell做了相当简洁的东西,实现了更好的语法,这在常规的Haskell中是不可能的,以及巨大的样板减少.那么为什么模板Haskell以这种方式受到鄙视呢?是什么让它不受欢迎?在什么情况下应避免模板Haskell,为什么?
我想要一个TemplateHaskell函数variablesInScope :: Q [Name],它返回Name范围内所有变量的列表.TemplateHaskell显然有这些信息可用于实现像reify :: Name -> Q Info和的功能lookupValueName :: String -> Q (Maybe Name).
我想要的功能是否存在于某个地方,我只是忽略了它?或者它可以以某种方式轻松建立?
我需要将编译脚本中的一些信息传递给Template Haskell.目前编译脚本将信息保存在系统环境中,所以我只是使用System.Environment.getEnvironmentwrap in来读取它runIO.有没有更好的方法,例如传递一些参数ghc(类似于-D...C预处理器),或者也许是为TH专门为此目的而设计的东西?
在我们的项目中,我们有很多TH生成的函数.向它们添加通用注释是有意义的,以便它们在Haddock/Hoogle中可见.至少,像"这是由TH生成的".有可能吗?
如您所知,Template Haskell用于在编译时以编程方式生成各种AST拼接.
然而,拼接通常可能非常不透明,并且通常难以辨别拼接实际生成的内容.如果你运行Qmonad进行拼接,并且拼接是良好类型的,你可以很好地show表示生成的AST片段,但由于其非结构化布局,这种表示很难理解.
将TH生成的AST转换为类似于普通Haskell代码的首选方法是什么,以便可以轻松读取和理解代码?可以从例如给定Dec值重建源代码吗?是否必须阅读GHC核心代码?有没有办法至少构建AST,使其变得更具可读性(超出pretty-show包裹的范围)?
我一直在使用用Haskell编写的Elm编译器.
我想开始为它实现一些优化,其中一部分涉及遍历AST并向某些节点添加"注释",例如尾调用等.
我知道我可以使用SYB或uniplate进行遍历,但我想知道是否有一种无样板的方法来处理类型.
所以,假设我们的AST有一堆代数类型:
data Expr = PlusExpr Expr Expr ...
data Def = TypeAlias String [String] Type ...
Run Code Online (Sandbox Code Playgroud)
如果我正在编写样板文件,我会创建这样的新类型:
data AnnotatedExpr = PlusExpr Expr Expr [Annotation] ...
data AnnotatedDef = TypeAlias String [String] Type [Annotation] ...
Run Code Online (Sandbox Code Playgroud)
这是很多写的boilderplate,并且似乎是避免这种做法的好习惯.
我可以这样写:
Data AnnotationTree = Leaf [Annotation]
| Internal [AnnotationTree] [Annotation]
Run Code Online (Sandbox Code Playgroud)
然后我就会有一个与AST并行运行的注释树.但是不能保证这些树具有相同的结构,因此我们失去了类型安全性.
所以我想知道,是否有一个优雅/推荐的解决方案,以避免样板,但仍然以类型安全的方式注释树?要用等效的节点替换每个节点,还有稍后将在编译中使用的注释列表?
haskell generic-programming ghc scrap-your-boilerplate template-haskell
是它在某种程度上可以做到具体化在GHCI?
当我使用'runQ'尝试它时,它抱怨"无法在IO monad中进行实现".
>>> runQ (reify ''Bool)
Template Haskell error: Can't do `reify' in the IO monad
*** Exception: user error (Template Haskell failure)
Run Code Online (Sandbox Code Playgroud)
我不是在找:t东西,只是为了快速检查什么reify返回而不将其写入文件并将该文件加载到GHCi中.
我想学习模板Haskell,但我找到的所有教程要么假设你学习了lisp并且知道什么是lisp宏,或者你知道一些cs理论行话 - 作为拼接,quasiquotations等等 - 或者关于宏的一些理论结果.
我不能编写一行lisp代码(虽然我打算有一天这样做,但我现在没时间学习它).Haskell是我的第一个函数式语言,我学到了它,我可以定期编写代码,使用monad,applicative,理解类型系统等等......但我不太了解(也想学习但是我对它来说太愚蠢......:P)关于它背后的理论背景.所以我对通常在TH教程中找到的术语一无所知.
因此,问题是:对于编写Haskell的人,有没有关于TH的教程,而不是作为一名专业的计算机科学家,而是作为一个使用编程进行日常琐事的人,他将Haskell作为他的第一个函数语言学习?也许介绍一下以TH为例的宏和元编程?
谢谢大家.:)
在McBride和Paterson的"有效的应用程序设计"中,他们介绍了一些可爱的语法糖来提升纯粹的功能:
[| f x y z |]
Run Code Online (Sandbox Code Playgroud)
对于
f <$> x <*> y <*> z
Run Code Online (Sandbox Code Playgroud)
我记得别人的地方使用li f w x y z il或il f v w x y z li,我想/希望,也许是因为它可以使用一些现有的语言功能和狡猾的定义来定义li和il.
我无法找到超越纸本的任何参考,并假设[|并|]不太可能在GHC任何时间很快转起来,是有可能实现li并il不知何故?我不能为他们想出一个合理的类型,所以我假设我需要模板Haskell或类似,但不知道几乎足以实现这一点.[af| f x y ]没关系,但我不知道在我开始尝试它之前是否可能,如果确实需要帮助.
haskell ×10
template-haskell ×10
ghc ×2
applicative ×1
comments ×1
compile-time ×1
ghci ×1
macros ×1
pretty-print ×1
reify ×1