【问题标题】:Generate a data declaration with TemplateHaskell使用 TemplateHaskell 生成数据声明
【发布时间】:2017-03-19 05:34:31
【问题描述】:

我想知道如何根据名称列表生成一堆常量。

我从这个工作示例开始:

ConstantCreation.hs

module ConstantCreation where

import Language.Haskell.TH

createConstant :: String -> Q [Dec]
createConstant constantName = do constantType   <- newName constantName
                                 constant       <- newName constantName
                                 return [ DataD []
                                          constantType []
                                          [NormalC constant []]
                                          []                       ]

MyConstants.hs

{-# LANGUAGE TemplateHaskell #-}

module MyConstants where

import ConstantCreation

$(do constantsDeclarations <- mapM createConstant
                                       [ "MyFirstCustomConstant"  ,
                                         "MySecondCustomConstant"   ]
     return $ mconcat constantsDeclarations)

但是当我尝试添加 deriving Show 时,事情变得很棘手。

我首先尝试像这样更改函数createConstant

createConstant constantName = do constantType   <- newName constantName
                                 constant       <- newName constantName
                                 return [ DataD []
                                          constantType []
                                          [NormalC constant []]
                                          [GHC.Show.Show]          ]

如果我在 GHCi 中运行命令 runQ [d|data MyConstant = MyConstant deriving Show|] 建议,但它会引发错误 Not in scope: data constructor ‘GHC.Show.Show’

所以我试着像这样定义我的函数:

createConstant constantName = [d|data $(ConT $ newName constantName) = $(NormalC (newName constantName) []) deriving Show|]

但后来我遇到了以下错误:

Cannot parse data constructor in a data/newtype declaration: $(NormalC
                                                                 (newName constantName) [])

不得不手动定义 Show 实例真的很可惜,所以我想知道发生了什么糟糕的事情。

感谢您的任何建议或解释。

【问题讨论】:

  • eleveConstr 是什么?
  • 什么是GHC.Show.Show?您可能想要代表名称的 TH 拼接 - ''ShowshowCon &lt;- mkName "Show"
  • @Sibi 我更正了代码。我将原始代码更改为自行记录示例,但忘记了。
  • @user2407038 我今晚试试。看起来它将修复第一个定义!但是我还是不明白第二个版本的问题。

标签: haskell template-haskell


【解决方案1】:

您可以使用''Show 获取名称在范围内的Type

{-# LANGUAGE TemplateHaskell #-}

module Constant where

import Language.Haskell.TH

createConstant constantName = do
    tname <- newName constantName
    cname <- newName constantName
    return [DataD [] tname [] [NormalC cname []] [''Show]]

【讨论】:

    猜你喜欢
    • 2011-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    • 2021-04-27
    相关资源
    最近更新 更多