【发布时间】:2021-04-29 20:01:18
【问题描述】:
我想通过以下方式导出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
如何获得所需的输出?
【问题讨论】:
-
“正确”的解决方案是始终使用漂亮的打印库(例如
prettyprinter)来实现人类可读的输出,并始终派生Show。这样,Show可以用于调试,因为它始终将完整值显示为有效的 Haskell 代码,可以将其输入 GHCi 或使用Read回读。Show的输出可以用pretty-show格式化,以提高可读性。 -
感谢您的评论。我明白这有什么意义,但是在这种情况下,我正在使用一个名为
string-interpolate的库,该库与Show一起工作(除其他外)。这里有一个很好的解释它是如何工作的:williamyaoh.com/posts/… -
@Jivan 但是
string-interpolate完全按照 Jon Purdy 的建议行事;它提供了自己的类型类Interpolatable。您应该使用自定义的漂亮打印机实例化它,并保留编译器生成的默认Show实例。事实上,这样的结果会更好,因为你可以直接产生一个Text,而不会引起两次字符串类型的转换。 (并且在您的链接中明确讨论了此类...) -
@DanielWagner 是的,完全有道理。感谢您指出这一点。