Dav*_*Fox 0 haskell template-haskell
我有一个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)
这是一个粗略的例子Lift。这确实不是目的Lift。lift新类型排除编译时副作用并非偶然。Lift用于序列化数据结构,这甚至在概念上都没有做到。如果这是序列化传递给它的数据结构,它将拼接在 IO 操作的表示中。这是执行一个操作并序列化该操作的结果。这不是不熟悉这段代码的人所期望发生的事情。
此外,自从 有了自己的实例以来,您投入序列化ByteString其组件的所有工作就不再是必要的了。bytestring-0.11.2.0Lift
但这里真正要做的只是编写一个执行您想要的操作的函数:
atCompileTime :: Lift a => IO a -> Q Exp
atCompileTime act = do
x <- runIO act
[| pure x |]
Run Code Online (Sandbox Code Playgroud)
它不是一个Lift实例,因此它可以具有允许它执行您想要的操作的类型。它不是一个Lift实例,因此它可以有一个名称来解释它实际上在做什么。作为奖励,它可以在 Haskell 模板的各种版本中工作。