标签: template-haskell

你怎么能有两个具有相同字段名称的记录?

我正在为JIRA编写JSON服务,并且我遇到了与Haskell命名空间冲突的要求.我有这个记录

data Assignee = Assignee {name :: Text} deriving Generic
instance ToJSON Assignee
Run Code Online (Sandbox Code Playgroud)

这是由JIRA想要的,不幸的是它想要一个不同的对象相同的字段.

data Reporter = Reporter {name :: Text} deriving Generic
instance ToJSON Reporter
Run Code Online (Sandbox Code Playgroud)

我看到几个选项:

  1. 也许我可以绕过编译器对模板Haskell的抱怨,但是如何?
  2. 我可能根本没有Reporter记录,并在创建故障单后用单独的服务更改记者字段.我知道怎么做,但这是最好的方式吗?
  3. 手动创建JSON对象,但我从此记录中创建它:

      data Fields = Fields 
              { project     :: HashMap Key Project
              , summary     :: Text
              , issuetype   :: HashMap Name Task
              , versions    :: [HashMap Name Text]
              , description :: Text
              , assignee    :: Assignee
              } deriving (Generic)
    
    Run Code Online (Sandbox Code Playgroud)

手工制作这个想法给了我一些感觉.如果我必须,我会.

所以,我现在的问题是,如果没有比我提出的方式更好的方法,那么这些是最好的行动方案?

json haskell template-haskell

2
推荐指数
2
解决办法
160
查看次数

在编译时按文件内容初始化函数

有没有办法初始化函数

someText :: Text
Run Code Online (Sandbox Code Playgroud)

哪个值将存储在编译时可用的文件中?

我以为我可以使用TH,但现在我才发现

embedFile :: FilePath -> Q Exp
runQ :: Quasi m => Q a -> m a
Run Code Online (Sandbox Code Playgroud)

我只能解开QIO:

instance Quasi IO    
instance Quasi Q
Run Code Online (Sandbox Code Playgroud)

我想我需要Quasi的Identity实例,但没有人.

haskell template-haskell

2
推荐指数
1
解决办法
116
查看次数

Haskell宏从他们的名字到一些表达式创建一个Map?

我有一些变数ab.我想Data.Map.fromList [("a",a),("b",b)]通过输入类似的东西来快速创建地图magic [a,b].我想在GHCI中这样做,而不是在模块中.

我花了一些时间学习模板Haskell,但我仍然无法判断它是否可能.是吗?

macros haskell introspection template-haskell

2
推荐指数
1
解决办法
65
查看次数

Yesod 中模板 haskell 的评估

在浏览 Yesod Book 的示例时,我遇到了以下代码片段的问题:

\n
{-# LANGUAGE OverloadedStrings #-}\n{-# LANGUAGE QuasiQuotes       #-}\n{-# LANGUAGE TemplateHaskell   #-}\n{-# LANGUAGE TypeFamilies      #-}\n{-# LANGUAGE ViewPatterns      #-}\nimport           Data.Text (Text)\nimport qualified Data.Text as T\nimport           Yesod\n\ndata App = App\ninstance Yesod App\n\nmkYesod "App" [parseRoutes|\n/person/#Text PersonR GET\n/year/#Integer/month/#Text/day/#Int DateR\n/wiki/*Texts WikiR GET\n|]\n\ngetPersonR :: Text -> Handler Html\ngetPersonR name = defaultLayout [whamlet|<h1>Hello #{name}!|]\n\nhandleDateR :: Integer -> Text -> Int -> Handler Text -- text/plain\nhandleDateR year month day =\n    return $\n        T.concat [month, " ", T.pack $ show day, ", ", T.pack $ show …
Run Code Online (Sandbox Code Playgroud)

haskell yesod template-haskell

2
推荐指数
1
解决办法
163
查看次数

避免不属于Haskell类的样板文件

我正在开发一个人工生命实验的框架.只要每个物种都是Agent类的一个实例,该框架就可以支持多个物种.我将每个Agent包装在AgentBox中,以便我可以在不知道底层类型的情况下读取,写入和使用它们.

这很好用,但是框架的用户必须编写一个小的样板函数.我很想知道是否有办法避免这种情况.我无法在Agent类中提供该函数的默认实现,因为函数的类型签名未提及类型变量.我可以忍受样板,但我很想知道是否有更好的方法.

这是我所谈论的最低工作范例.最后的getRock函数是我想避免强迫用户编写的函数.类Agent的每个实例都需要提供一个读取代理并将其包装在一个框中的函数,并且实现看起来总是与getRock完全相同.

{-# LANGUAGE ExistentialQuantification, DeriveGeneric #-}

import qualified Data.Serialize as DS (Get, Serialize, get, put)
import Data.Serialize.Put (PutM)
import Data.List (find)
import Data.Maybe (fromJust, isNothing)
import GHC.Generics ( Generic )

class Agent a where
  agentId :: a -> String
  speciesId :: a -> String
  -- other functions to be added

-- This wrapper allows me to use Agents without knowing their type.
data AgentBox = forall a. (DS.Serialize a, Agent a) => AgentBox a

-- Instructions for deserialising …
Run Code Online (Sandbox Code Playgroud)

generics haskell scrap-your-boilerplate template-haskell

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

数据类型Haskell错误

我声明了一些数据类型如下:

data TX_OR_TY = TX | TY
data TX = X Int
data TY = Y Float

现在我写一些函数返回它们的数据类型:

funcTX :: TX
funcTX = X 3

funcTY :: TY
funcTY = Y 5

ordFuncTX :: TX -> Int -> Bool
ordFuncTX (X a) b = (a > b)

funcTX_TY :: TX_OR_TY
funcTX_TY = if (ordFuncTX funcTX 4) then funcTX else funcTY

函数funcTX_TY将通过比较TX的值与4返回TX_OR_TY类型,如果大于则返回TX,如果小则返回TY.但在编译时,它宣布它无法将预期类型TX_OR_TYTX匹配.我该怎么办?

haskell haskell-platform template-haskell

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

一个quasiquoter'使用'变量可以在它被调用的同一个文件中定义吗?

所以,我开始尝试quasiquotation和模板haskell.

我想修改一个现有的(大)准规则代码,同时使用在"被调用"的地方定义的变量的实际值.举一个简单的例子说明:

main.hs

{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}

import Language.Haskell.TH
import Exp02

x = "cde"

main = do
  putStrLn [str|$x|]
Run Code Online (Sandbox Code Playgroud)

Exp02.hs

{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}

module Exp02 where

import Language.Haskell.TH
import Language.Haskell.TH.Syntax
import Language.Haskell.TH.Quote

xpto :: String -> ExpQ
xpto [] = stringE []
xpto ('$':rest) = varE (mkName rest)
xpto str = stringE str

str = QuasiQuoter
  { quoteExp = xpto
  , quotePat = fail $ "patterns"
  , quoteType= fail $ "types" …
Run Code Online (Sandbox Code Playgroud)

haskell template-haskell

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

是否可以使用Template Haskell发出原始源代码?

假设我有一个String(或者Text其他)包含有效的Haskell代码.有没有办法将其转换为[Dec]模板Haskell?

我很确定AST没有直接进入GHC,因此无论如何都会有打印然后解析阶段.

这将是很好的,因为它将允许TH的不同"后端".例如,你可以使用AST haskell-src-exts支持比TH更多的Haskell语法.

haskell template-haskell

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

TemplateHaskell 未安装...然后是

我正在用 Haskell 编写一个程序,它涉及很多括号。因此,为了清理那一团丑陋的混乱,我使用了$几次运算符来使其更易于阅读。例如:

longFunc arg1 (anotherFunc (yetAnotherFunc arg2))
Run Code Online (Sandbox Code Playgroud)

被替换为

longFunc arg1 $ anotherFunc $ yetAnotherFunc arg2
Run Code Online (Sandbox Code Playgroud)

但是当我使用 GHCi 编译我的程序时,我收到一条消息:

MyFile.hs:18:18: error:
    parse error on input ‘$’
    Perhaps you intended to use TemplateHaskell
Failed, modules loaded: none.
Run Code Online (Sandbox Code Playgroud)

这是第 16-18 行:

MyFile.hs:18:18: error:
    parse error on input ‘$’
    Perhaps you intended to use TemplateHaskell
Failed, modules loaded: none.
Run Code Online (Sandbox Code Playgroud)

我很困惑,因为我已经多次使用该$运算符(使用相同的编译器),如下所示:

isDigit :: Char -> Bool
isDigit c =
  c `elem` $ ['0'..'9'] ++ "."
Run Code Online (Sandbox Code Playgroud)

所以我将该代码作为测试输入到我的文件中,删除了其他$出现的内容,然后加载了它。

它奏效了!

有人可以告诉我这是怎么回事吗?

haskell template-haskell

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

Haskell:makeLenses - 数据构造函数不在范围内

我在这里有这个简单的代码来定义类型并用于makeLenses生成镜头。

module Api.Jira.Types.Search
  (
    SearchRequest(..)
  ) where

import GHC.Generics
import qualified Data.Text as T
import Data.Aeson (FromJSON, ToJSON)
import Control.Lens
import Data.Aeson
import Data.Aeson.Types

data SearchRequest = SearchRequest
  { _jql :: T.Text
  , _startAt :: Maybe Int
  , _maxResults :: Maybe Int
  , _fields :: Maybe [T.Text]
  , _expand :: Maybe [T.Text]
  , _properties :: Maybe [T.Text]
  } deriving (Show, Generic)

instance ToJSON SearchRequest where
  toJSON = genericToJSON defaultOptions {
             fieldLabelModifier = drop 1 }

instance FromJSON SearchRequest …
Run Code Online (Sandbox Code Playgroud)

haskell template-haskell

0
推荐指数
1
解决办法
421
查看次数

如何将此 Template Haskell Lift 实例迁移到版本 2.18

我有一个Lift适用于 template-haskell 2.14 的实例,但无法使用更高版本进行编译。有人可以解释需要进行哪些更改吗?

{-# LANGUAGE FlexibleInstances, TemplateHaskell #-}

module LiftBS where

import Data.ByteString as B (ByteString, length, unpack)
import Data.ByteString.Unsafe (unsafePackAddressLen)
import Language.Haskell.TH (runIO, litE, stringPrimL)
import Language.Haskell.TH.Lift (Lift(lift))

instance Lift (IO B.ByteString) where
  lift bsio = do
    bs <- runIO bsio
    [|unsafePackAddressLen $(lift (B.length bs)) $(litE (stringPrimL (B.unpack bs))) :: IO ByteString|]
Run Code Online (Sandbox Code Playgroud)

haskell template-haskell

0
推荐指数
1
解决办法
86
查看次数

Haskell 中编译时参数的混淆值

在我的 Haskell 应用程序中,我实现了以下机制来将敏感信息传递到二进制文件(不诉诸 CLI 参数):

  • 我使用一种TemplateHaskell在编译时读取环境变量的机制:
{-# LANGUAGE TemplateHaskell #-}
...
import Language.Haskell.TH.Env
...
myPrecious :: String
myPrecious = fromMaybe "" $$(envQ "MY_PRECIOUS")
...
Run Code Online (Sandbox Code Playgroud)
  • 编译时,我像这样传递相关的环境变量:MY_PRECIOUS=<secret> stack build然后它绑定到myPreciousHaskell 端
  • 生成的二进制文件具有编译后的值,因此从操作系统级别(例如 via )MY_PRECIOUS看不到它ps aux

问题是,我现在可以在文本编辑器中打开该二进制文件或创建内存转储(例如使用 GDB),并通过一点决心挖掘秘密,特别是如果我知道它正在使用的上下文 - 我假设某些恶意行为者可能已经获得了源代码的访问权限。所以我一直想知道,是否有任何方法可以强制 GHC 生成更加混乱/乱码的二进制文件,其中这些值不容易可见。我知道没有这样的保护方案可以是万无一失的,但我正在寻找一种方法来使入侵者的任务变得更加困难。

security haskell decompiling dump template-haskell

0
推荐指数
1
解决办法
113
查看次数

在Haskell中获取系统时间的方法是什么?

我想在我的代码中使用系统时间来记录从用户界面捕获数据时的时间。如何使用Haskell获取系统时间

haskell haskell-platform template-haskell haskell-pipes haskell-stack

-3
推荐指数
1
解决办法
65
查看次数