我正在为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)
我看到几个选项:
手动创建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)手工制作这个想法给了我一些感觉.如果我必须,我会.
所以,我现在的问题是,如果没有比我提出的方式更好的方法,那么这些是最好的行动方案?
有没有办法初始化函数
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)
我只能解开Q到IO:
instance Quasi IO
instance Quasi Q
Run Code Online (Sandbox Code Playgroud)
我想我需要Quasi的Identity实例,但没有人.
我有一些变数a和b.我想Data.Map.fromList [("a",a),("b",b)]通过输入类似的东西来快速创建地图magic [a,b].我想在GHCI中这样做,而不是在模块中.
我花了一些时间学习模板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) 我正在开发一个人工生命实验的框架.只要每个物种都是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) 我声明了一些数据类型如下:
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_TY与TX匹配.我该怎么办?
所以,我开始尝试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) 假设我有一个String(或者Text其他)包含有效的Haskell代码.有没有办法将其转换为[Dec]模板Haskell?
我很确定AST没有直接进入GHC,因此无论如何都会有打印然后解析阶段.
这将是很好的,因为它将允许TH的不同"后端".例如,你可以使用AST haskell-src-exts支持比TH更多的Haskell语法.
我正在用 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)
所以我将该代码作为测试输入到我的文件中,删除了其他$出现的内容,然后加载了它。
它奏效了!
有人可以告诉我这是怎么回事吗?
我在这里有这个简单的代码来定义类型并用于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) 我有一个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 应用程序中,我实现了以下机制来将敏感信息传递到二进制文件(不诉诸 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 端MY_PRECIOUS看不到它ps aux问题是,我现在可以在文本编辑器中打开该二进制文件或创建内存转储(例如使用 GDB),并通过一点决心挖掘秘密,特别是如果我知道它正在使用的上下文 - 我假设某些恶意行为者可能已经获得了源代码的访问权限。所以我一直想知道,是否有任何方法可以强制 GHC 生成更加混乱/乱码的二进制文件,其中这些值不容易可见。我知道没有这样的保护方案可以是万无一失的,但我正在寻找一种方法来使入侵者的任务变得更加困难。
我想在我的代码中使用系统时间来记录从用户界面捕获数据时的时间。如何使用Haskell获取系统时间。
haskell haskell-platform template-haskell haskell-pipes haskell-stack
haskell ×13
template-haskell ×13
decompiling ×1
dump ×1
generics ×1
json ×1
macros ×1
security ×1
yesod ×1