首页 > 解决方案 > 在新类型上派生 Show 时避免使用双引号

问题描述

我想通过以下方式导出来打印 a 的内部值newtypeShow这样我就不必Value val每次需要打印时都打开包装。

{-# LANGUAGE OverloadedStrings          #-}

import Data.Text

newtype Value = Value Text
instance Show Value where show (Value val) = show val


main :: IO ()
main = do
    let hello = Value "hello"
        world = Value "world"
    print $ show hello <> ", " <> show world
    pure ()

这个想法是我可以简单地show hello而不是做let Value helloVal = hello in show helloVal(有点人为的例子,但重点是避免展开)。

问题是这会打印以下内容:

"\"hello\", \"world\""

而期望的结果是:

hello, world

如何获得所需的输出?

标签: haskellshownewtype

解决方案


一般约定Show是它应该生成或多或少的 Haskell 代码,在大多数简单的情况下,您可以直接从 GHCi 输出中复制出来并直接插入到其输入中。

这就是为什么show "foo"产生一个"\"foo\""带引号的字符串。因此,当它在 GHCi 中打印时,您会看到引号。这也是为您的类型生成默认派生实例的原因"Value \"foo\""- 这是直接的 Haskell 代码,可以编译和评估以生成原始Value值。

但是,如果您真的不想要额外的引号 - 当然,只需将您转换TextStringusing unpack

instance Show Value where show (Value v) = unpack v

推荐阅读