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

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)

Car*_*arl 6

这是一个粗略的例子Lift。这确实不是目的Liftlift新类型排除编译时副作用并非偶然。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 模板的各种版本中工作。