在新类型上派生 Show 时避免使用双引号
Avoid double quotes when deriving Show on newtype
我想通过以下方式导出 Show
来打印 newtype
的内部值,这样我就不必每次都需要解包 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
如何得到想要的输出?
行中
show (Value val) = show val
您在 val
上使用 show
,这是 Text
。这会将 val
转换为 String
执行引用和转义。如果您不希望这样,请改用 unpack val
。
最后,请注意,如果没有正确引用,show
的输出在调用时可能会模棱两可,例如 Value
的列表。在这种情况下,如果 show
的输出是 [a, b, c]
我们无法知道列表的长度是 3、2 还是 1,因为逗号可能是 [=13= 的一部分]在里面。
要从 Text
到 String
而不用引号引起来,请使用 unpack
。
instance Show Value where
show (Value val) = unpack val
此外,请注意 print
等同于 putStrLn . show
,因此您实际上是在值上调用 show
两次,第一次是 Value
,第二次是 String
。如果你已经有一个字符串,你需要使用 putStrLn
而不是 print
.
putStrLn $ show hello <> ", " <> show world
Show
的一般约定是它应该产生或多或少的 Haskell 代码,在大多数简单的情况下,您可以直接从 GHCi 输出中复制出来并直接插入其输入。
这就是 show "foo"
生成字符串 "\"foo\""
的原因 - 带引号。这样当它在 GHCi 中打印时,您会看到引号。这也是为什么您的类型的默认派生实例会生成 "Value \"foo\""
- 这是直接的 Haskell 代码,可以编译和评估以生成原始 Value
值。
但如果您真的不想要额外的引号 - 当然,只需使用 unpack
:
将 Text
转换为 String
instance Show Value where show (Value v) = unpack v
我想通过以下方式导出 Show
来打印 newtype
的内部值,这样我就不必每次都需要解包 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
如何得到想要的输出?
行中
show (Value val) = show val
您在 val
上使用 show
,这是 Text
。这会将 val
转换为 String
执行引用和转义。如果您不希望这样,请改用 unpack val
。
最后,请注意,如果没有正确引用,show
的输出在调用时可能会模棱两可,例如 Value
的列表。在这种情况下,如果 show
的输出是 [a, b, c]
我们无法知道列表的长度是 3、2 还是 1,因为逗号可能是 [=13= 的一部分]在里面。
要从 Text
到 String
而不用引号引起来,请使用 unpack
。
instance Show Value where
show (Value val) = unpack val
此外,请注意 print
等同于 putStrLn . show
,因此您实际上是在值上调用 show
两次,第一次是 Value
,第二次是 String
。如果你已经有一个字符串,你需要使用 putStrLn
而不是 print
.
putStrLn $ show hello <> ", " <> show world
Show
的一般约定是它应该产生或多或少的 Haskell 代码,在大多数简单的情况下,您可以直接从 GHCi 输出中复制出来并直接插入其输入。
这就是 show "foo"
生成字符串 "\"foo\""
的原因 - 带引号。这样当它在 GHCi 中打印时,您会看到引号。这也是为什么您的类型的默认派生实例会生成 "Value \"foo\""
- 这是直接的 Haskell 代码,可以编译和评估以生成原始 Value
值。
但如果您真的不想要额外的引号 - 当然,只需使用 unpack
:
Text
转换为 String
instance Show Value where show (Value v) = unpack v