gpt4 book ai didi

haskell - 更改 Setup.hs 的构建方式

转载 作者:行者123 更新时间:2023-12-03 15:15:41 27 4
gpt4 key购买 nike

encoding包使用 HaXml在其构建脚本中(在 Setup.hs 中)。它碰巧使用了在 HaXml-1.19 和 HaXml-1.22 之间更改的接口(interface)位。如果编码包能够使用任一版本构建,那就太好了。我尝试使用通常的 cabal 技巧,即做类似的事情

{-# LANGUAGE CPP #-}
#if MIN_VERSION_HaXml(1,22,0)
-- HaXml-1.22 code
#else
-- HaXml-1.19 code
#endif

...但是在配置包之前不能存在魔术定义,并且正在构建此文件以使配置步骤成为可能。我有哪些选择?有没有办法改变 cabal-install 调用编译的命令 Setup.hs ?是否有另一种有条件地选择避开 cabal 的代码的机制?

最佳答案

Data.Data接口(interface)能够(几乎!)构造和解构可能存在或不存在的类型的值。不幸的是,HaXml 似乎没有 Data它的类型的实例,你不能定义一个,因为你不能引用可能存在或可能不存在的类型,所以我们不得不求助于 Template Haskell:

以下模块导出 qnameCompat :

{-# LANGUAGE TemplateHaskell #-}
module HaXmlCompat (qnameCompat) where

import Language.Haskell.TH

qnameCompat :: Q [Dec]
qnameCompat = do
mi <- maybeReify "N"
case mi of
Nothing -> sequence [
tySynD (mkName "QName") [] [t| String |],
valD [p| toQName |] (normalB [| id |]) [],
valD [p| fromQName |] (normalB [| Just |]) []]
Just (DataConI n _ _ _) -> do
s <- newName "s"
sequence [
valD [p| toQName |] (normalB (conE n)) [],
funD (mkName "fromQName") [
clause [conP n [varP s]] (normalB (appE [| Just |] (varE s))) [],
clause [ [p| _ |] ] (normalB [| Nothing |]) []]]
Just i -> fail $
"N exists, but isn't the sort of thing I expected: " ++ show i

maybeReify :: String -> Q (Maybe Info)
maybeReify = recover (return Nothing) . fmap Just . reify . mkName

当使用 Template Haskell 在顶层拼接时, qnameCompat将检查 N存在。如果是这样,它会生成以下代码:
toQName = N
fromQName (N s) = Just s
fromQName _ = Nothing

如果没有,则生成以下内容:
type QName = String
toQName = id
fromQName = Just

现在您可以创建和解构 Element s,例如使用 ViewPatterns 扩展:
myElt :: String -> Element i
myElt = Elem (toQName "elemName") [] []

eltName :: Element i -> String
eltName (Elem (fromQName -> Just n) _ _) = n

ViewPatterns 很方便,但不是必须的,当然:对 fromQName 的结果使用普通模式匹配也可以。

(这些想法促使我开发了 notcpp package ,其中包括 maybeReify 和其他一些有用的实用程序)

关于haskell - 更改 Setup.hs 的构建方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10256042/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com