我想学习模板Haskell,但我找到的所有教程要么假设你学习了lisp并且知道什么是lisp宏,或者你知道一些cs理论行话 - 作为拼接,quasiquotations等等 - 或者关于宏的一些理论结果.
我不能编写一行lisp代码(虽然我打算有一天这样做,但我现在没时间学习它).Haskell是我的第一个函数式语言,我学到了它,我可以定期编写代码,使用monad,applicative,理解类型系统等等......但我不太了解(也想学习但是我对它来说太愚蠢......:P)关于它背后的理论背景.所以我对通常在TH教程中找到的术语一无所知.
因此,问题是:对于编写Haskell的人,有没有关于TH的教程,而不是作为一名专业的计算机科学家,而是作为一个使用编程进行日常琐事的人,他将Haskell作为他的第一个函数语言学习?也许介绍一下以TH为例的宏和元编程?
谢谢大家.:)
Safe Haskell的文档说明:
[...]不幸的是,模板Haskell可用于破坏模块边界,因此可用于获取对此构造函数的访问权限.[...]使用-XSafe标志编译Danger模块会限制可用于安全子集的Haskell功能.这包括禁止不安全的PerfromIO,模板Haskell,[...]
用作将AST转换为另一个AST的宏系统,是否不能简单地将TH限制为Haskell的安全子集,并将结果AST限制为该子集?
我正在关注Yesod的书,其中指出:
但是通过使用-ddump-splices GHC选项,我们可以立即查看生成的代码.一个很清理的版本是:
我该怎么做?我已经尝试用我的文件编译ghc -XTemplateHaskell -ddump-splices Page.hs,它留下了如下目录:
Page Page.hi Page.hs Page.hs~ Page.o
但是,这些文件都不包含Template Haskell生成的中间代码.
我有一个TH重文件,编译大约需要30秒.我可以使用哪些技术来帮助调试Template Haskell的性能?
我想和Lens图书馆玩一下.我已将其加载到GHCi中并使用适当的下划线创建记录数据类型:
> data Foo a = Foo {_arg1 :: Int, _arg2 :: [a]}
Run Code Online (Sandbox Code Playgroud)
我想制作Foo使用makeLenses模板的镜头.我想这样做而不需要阅读整套Template-Haskell文档.
我可以在GHCi提示符下输入什么咒语来使其工作?
假设我有两种类型:
t1 <- [t| (Functor f) => (a -> b) -> f a -> f b |]
t2 <- [t| (Int -> Char) -> [Int] -> [Char] |]
Run Code Online (Sandbox Code Playgroud)
是否有可能在Template Haskell中确定表达式t1也可以是t2?(我自己没有实现类型统一.)
说我有以下内容:
data Rec = Rec {
alpha :: Int,
beta :: Double,
phi :: Float
}
sample = Rec 1 2.3 4.5
Run Code Online (Sandbox Code Playgroud)
我理解模板Haskell和reify函数可以得到记录的字段名称.那是:
print $(f sample) --> ["alpha", "beta", "phi"]
Run Code Online (Sandbox Code Playgroud)
还有一种说法是,这可以在没有Template Haskell的情况下完成.有人可以为此提供一个示例实现吗?
给定一个表达式foo,我可以声明一个顶级函数
bar = foo
Run Code Online (Sandbox Code Playgroud)
并通过reifying获得fooas 类型:Type bar
case reify 'bar of
VarI _ t _ _ -> t
Run Code Online (Sandbox Code Playgroud)
是否有直接获取类型的方法foo,而不创建冗余的定义bar?理想情况下作为类型的函数Exp -> Q Type.
在Haskell中,如果我想重复将一个内同态a -> a应用于a我可以使用的类型的值iterate.
那个函数不是一个endomorphisms,但通用到足以在返回类型上正常工作?
考虑一下Just :: a -> Maybe a; 我可以写
Just . Just . Just ...
Run Code Online (Sandbox Code Playgroud)
我想要多次.有没有办法用这样的东西写这个
iterate' 3 Just :: a -> Maybe (Maybe (Maybe a))
Run Code Online (Sandbox Code Playgroud)
或者我们需要像依赖类型这样的东西吗?
我写了一些TemplateHaskell发出重写规则的代码,但是GHC(8.6.5)拒绝了我的规则,并出现以下错误:
Rule "mapKWith/Pure":
Illegal expression: ((mapKWith @Pure) constraintProxy)
in left-hand side: ((mapKWith @Pure) constraintProxy) func
LHS must be of form (f e1 .. en) where f is not forall'd
Run Code Online (Sandbox Code Playgroud)
如果我使用编译-ddump-splices并查看该规则,则可以看到它看起来像这样(重新格式化):
{-# RULES "mapKWith/Pure"
forall
(constraintProxy :: Proxy constraint)
(func :: forall child. constraint child => Tree m child -> Tree n child).
((mapKWith @Pure) constraintProxy) func =
\case MkPure x -> MkPure (func x)
#-}
Run Code Online (Sandbox Code Playgroud)
如果我将此规则复制到代码中并进行编辑,则只需要删除LHS的多余括号,GHC就可以接受它(这样LHS就变得mapKWith @Pure constraintProxy func没有括号了)。
有没有一种方法可以从TH发出没有多余括号的代码,以便GHC可以接受它来重写规则LHS?还有其他解决方案或解决方法吗?
对于上下文,我正在尝试生成这些规则来帮助GHC内联函数获取RankNTypes值,并且我尝试的代码可在https://github.com/lamdu/syntax-tree/blob/rewrite-rules/src中 …
haskell ×10
template-haskell ×10
ghc ×2
reify ×2
types ×2
expression ×1
ghci ×1
haskell-lens ×1
macros ×1