标签: template-haskell

强制预先计算常数

我在Haskell中有一个持续的声明 - 我可以提前对它进行评估吗?我看到一些看起来很像的代码,

myList = [(a, b), (c, d)]
...
map (f . fst) myList
Run Code Online (Sandbox Code Playgroud)

fst当我对它进行分析时,它会在通话中占用一些时间(它有168M的呼叫).二进制表示myList非常小,例如,可以复制到全局内存[如果这是一个C程序].我正在编译-O3 -optc-O3.

非常感谢!

为自定义类型生成Lift实例

lift在sclv的答案中给出调用的任何表达式都必须是Lift的一个实例.有一个名为library的库th-lift,它将为自定义数据类型生成Lift实例.查看该软件包的文档.

performance haskell lazy-evaluation compile-time template-haskell

13
推荐指数
1
解决办法
860
查看次数

使用Scala生成代码

在Scala中使用SBT工具链时,是否可以编写一个任务来读取项目源的特殊部分,以便在编译时生成scala-code.

关于这个的任何想法甚至文章/教程?我正在寻找与Template Haskell相似的东西.

code-generation scala template-haskell

13
推荐指数
3
解决办法
5985
查看次数

如何摆脱$(...)和[| 使用Template Haskell函数时的... |]语法?

我正在尝试学习一些模板Haskell.作为练习,我写的,可以生成诸如函数isLeftisRight(灵感来自这个问题).这是我谦虚的尝试:

isA connam = do
    ConE nam <- connam
    nn <- newName "p"
    lamE [varP nn] $ caseE (varE nn) [
                       match (conP nam [wildP]) ( normalB [| True |] ) [],
                       match wildP ( normalB [| False |] ) [] 
                     ]
Run Code Online (Sandbox Code Playgroud)

问题是我必须写$(isA [| Left |])而不是更直观isA Left.是否有可能摆脱丑陋的语法?我似乎无法在文档中找到答案.

该函数仅适用于单参数构造函数,但这是另一个问题.

haskell template-haskell

12
推荐指数
1
解决办法
469
查看次数

如何为 Template Haskell 拼接编写属性测试?

我总是喜欢能够为我的代码编写属性测试。当该代码是 Template Haskell 时,我最感兴趣的是生成的代码的行为。直觉上,我希望能够写出类似的东西

import Test.QuickCheck

checkLift :: (Eq a, Lift a, Show a) => a -> Property
checkLift a = $$(liftTyped a) === a

prop_myLiftWorks :: MyType -> Property
prop_myLiftWorks = checkLift
Run Code Online (Sandbox Code Playgroud)

不幸的是,Template Haskell 阶段的限制使得这种精确的方法完全不可能。生成的拼接必须单独编译才能运行。是否有一些简单的方法可以在测试套件中启动 GHC 实例(或对包执行某些操作ghchaskell-language-server?)并对其进行拼接?

理想情况下,我希望能够使用声明拼接和表达式拼接。例如,要为 编写属性测试deriving-compat,我想要生成各种类型的任意数据类型声明,然后将 Template Haskell 派生的实例与 GHC 派生的实例进行比较。

haskell template-haskell

12
推荐指数
0
解决办法
169
查看次数

模板haskell中的数据构造函数

我正在尝试创建环Z/n(像普通算术一样,但模数为整数).一个示例实例是Z4:

instance Additive.C Z4 where
  zero = Z4 0
  (Z4 x) + (Z4 y) = Z4 $ (x + y) `mod` 4
Run Code Online (Sandbox Code Playgroud)

对于戒指等等.我希望能够快速生成这些东西,我认为这样做的方法是使用模板haskell.理想情况下,我只是想让$(makeZ 4)Z4像上面定义的那样吐出代码.

我虽然遇到了很多麻烦.当我这样做时,genData n = [d| data $n = $n Integer]我得到"数据/新类型声明中的解析错误".如果我不使用变量[d| data Z5 = Z5 Integer |],它确实有效:这必然意味着我正在做一些奇怪的变量.我不确定是什么; 我尝试通过newName构建它们,但似乎也没有用.

任何人都可以帮我解决这里发生的事情吗?

haskell template-haskell

11
推荐指数
1
解决办法
1835
查看次数

使用Template Haskell,如何将相同类型拼接到多个位置?

我正在从矢量空间OpenGL类型定义类的实例,并且为了节省我的打字肌肉,我想使用Template Haskell为我编写一堆实例.

我开始时通过定义函数来派生实例AdditiveGroup:

{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
module Data.VectorSpace.OpenGL.TH where

import Control.Applicative
import Control.Monad
import Data.AdditiveGroup
import Data.VectorSpace

import Language.Haskell.TH

deriveScalarAdditive ts = concat <$> forM (map conT ts) (\t -> [d| 
    instance AdditiveGroup $t where zeroV = 0; (^+^) = (+); negateV = negate
  |])
Run Code Online (Sandbox Code Playgroud)

这很好,但请注意,我只是拼接$t到牛津支架一次.现在,派生VectorSpace实例的函数:

deriveScalarVectorSpace ts = concat <$> forM (map conT ts) (\t -> [d|    
    instance …
Run Code Online (Sandbox Code Playgroud)

haskell template-haskell

11
推荐指数
1
解决办法
732
查看次数

Haskell: Template Haskell and the scope

This code is compiled fine:

data None = None { _f :: Int }
type Simpl = Env

type Env = Int
Run Code Online (Sandbox Code Playgroud)

However, I got an error with this code:

{-# LANGUAGE TemplateHaskell #-}
import Control.Lens

data None = None { _f :: Int }

type Simpl = Env

makeLenses ''None

type Env = Int
Run Code Online (Sandbox Code Playgroud)

Error:

Not in scope: type constructor or class `Env'
Run Code Online (Sandbox Code Playgroud)

I just added a single line makeLenses ''None between type declarations.
This means TemplateHaskell code could …

haskell template-haskell haskell-lens

11
推荐指数
1
解决办法
1038
查看次数

我可以使用模板haskell来定义缺失的函数吗?

我有一种情况需要在不同的机器上编译一些Haskell代码.这些机器中至少有一台有一个相当旧版本的Control.Concurrent.STM,它不知道modifyTVar.我目前的解决方法是从较新版本的软件包中复制modifyTVar的代码.这让我想知道,是否可以使用模板Haskell来检查函数是否已经定义并且只定义它,如果它丢失了.我知道正确的解决方案可能是获得更新的软件包,但这种情况让我很好奇.

haskell stm template-haskell

11
推荐指数
1
解决办法
202
查看次数

使用Template Haskell添加要链接的库

我目前正试图通过在Haskell中编写Rust代码内联的quasiquotes进行攻击.我认为我已经完成了代码生成工作(包括将生成的Rust之类的Haskell类型封送起来).我现在有一个问题,即从模板Haskell中找出如何进行所有编译和链接.管道如下:

  1. quasiquote得到解析
  2. 生成源代码
    • 相应的Rust函数
    • Haskell FFI进口
    • Haskell调用导入的函数
  3. Rust代码被编译成静态库(如rustc --crate-type=staticlib qq_function.rs -o qq_function.a)
  4. Haskell的代码被编译并链接qq_function.a(以及其它类似的图书馆屈指可数m,c等等)

我的问题是让步骤3和4完全发生TemplateHaskell.据我所知,这是:

  • runIO 可以写出我生成的Rust源文件
  • addDependentFile 通知GHC生成的Rust文件是依赖项
  • addForeignFile遗憾的是并没有以来锈是不支持的语言自动管理的编制工作(这是该方法inline-c需要因为C语言一个支持的语言)
  • runIO可以通过调用来生成静态Rust库(并在之后删除Rust源文件)rustc.

我还不太清楚的是

  1. 我如何使用Template Haskell添加链接的库和
  2. 我怎样才能使用Template Haskell来清理这些生成的库?

编辑

我已经提交了与此相关的GHC功能请求.

haskell ffi ghc template-haskell

11
推荐指数
0
解决办法
171
查看次数

是否有模板haskell函数用于引用?

我正在玩模板Haskell.我想创建一个准引号,它允许我为记录创建默认初始值设定项,例如

[record| data Config = { shouldDoX = True; featureY :: Integer, optionZ = Nothing } |]
Run Code Online (Sandbox Code Playgroud)

应该创建一个功能

defaultConfig = Config { shouldDoX = True, optionZ = Nothing }
Run Code Online (Sandbox Code Playgroud)

基本上它与数据声明的语法相同,默认值扩展.现在record是一个自定义QuasiQuoter,但是有些表达式和类型我不想解析自己.理想情况下,我只需要将花括号内的块分成语句并查找=::.

所以我正在寻找一个有效的功能与引用[e| ...|]或相同的功能[t| ...|].我搜索过Hoogle的功能String -> ExpQ,String -> Q Exp但没有找到任何东西.

如果我不清楚我在寻找什么:我知道QuasiQuoters.正如我所提到的:record QuasiQuoter.现在传递给我的准引号的字符串包含表达式(如Node 7 (Node 8 Nil Nil) Nil)和类型(如TrueMaybe (Either A B)).我可以自己解析这些,但我希望有一个函数可以为我做,就像我把字符串传递给像这样的引号[e|...|].

所以:我正在寻找一个函数,我可以将表达式作为String,或者Type作为String,并返回适当的ExpType对象.我相信它必须存在于Q monad中,因为它应该根据上下文来评估表达式或类型(就像引用一样). …

haskell template-haskell

10
推荐指数
1
解决办法
479
查看次数