【问题标题】:`show` record without deriving Show`show` 记录没有派生 Show
【发布时间】:2018-03-25 21:59:15
【问题描述】:

调试时我经常需要打印一些东西,除非我需要查看的数据类型派生Show,否则我无法打印它。对于某些数据类型,我无法将 deriving (Show) 添加到定义中,因为它可能位于库中或我无法到达的其他地方。

我是否可以打印这些数据类型以进行调试?

【问题讨论】:

  • 出于好奇,您能否举一个类型库的示例,该库的类型缺少您想要的 Show 实例?
  • Yesod 模型创建的类型。我认为这些是在模板 Haskell 中定义的,所以我无法找到它们。
  • 哦?看起来这里的所有示例都有一个deriving Show 子句yesodweb.com/book/persistent

标签: haskell


【解决方案1】:

独立派生

类型定义上的deriving 子句不是派生的唯一方法。您也可以使用StandaloneDeriving GHC 语言扩展。

λ> :set -XStandaloneDeriving

λ> data Person = Human { name :: String, age :: Int } | Dog { goodPupper :: Bool }

λ> deriving instance Show Person

λ> Human "Chris" 31
Human {name = "Chris", age = 31}

泛型

如果该类型有一个Generic 实例,您可以使用generic-deriving 包中的gshowsPrecdefault 函数对其进行字符串化。

λ> import GHC.Generics
λ> import Generics.Deriving.Show

λ> data Person = Human { name :: String, age :: Int } | Dog { goodPupper :: Bool } deriving Generic

λ> putStrLn $ gshowsPrecdefault 0 (Dog True) ""
Dog {goodPupper = True}

GHCi:强制

您可以在 GHCi 中使用:force 命令来检查一个值。

λ> data Person = Human { name :: String, age :: Int } | Dog { goodPupper :: Bool }

λ> x = Human "Chris" 31

λ> x
<interactive>:17:1: error:
    • No instance for (Show Person) arising from a use of ‘print’
    • In a stmt of an interactive GHCi command: print it

λ> :force x
x = <Human> "Chris" 31

请参阅 GHC 手册中的Breakpoints and inspecting variables

【讨论】:

  • Force 似乎很有帮助,但大多数时候我需要在从 stack test 而不是 ghci 运行的测试中执行此操作。
【解决方案2】:

如果您想以任何方式打印它,您必须将您的数据类型设为Show 的实例。如果您不想派生Show,您可以随时自己实现。

data Foo = Bar

instance Show Foo where
  show Bar = "This is Bar"

main = print f where f = Bar

【讨论】:

  • 有没有办法不设置它将显示的文本,而是显示 Bar 内的所有字段,就像派生显示一样?
  • @Qwertie 是的,您只需要不设置它将显示的文本,而是显示 Bar 内的所有字段,例如 show (Bar x y z) = "Bar " ++ show x ++ ' ':show y ++ ' ':show z
  • 格式化挑剔:&lt;!-- language: lang-haskell --&gt;doesn't actually add Haskell highlighting.
【解决方案3】:

您完全可以在没有 Show 实例的情况下打印内容。

data MyType a = MyType Int a
showMyType :: (a -> String) -> MyType a -> String
showMyType f (MyType n a) =
  "MyType " ++ show n ++ " (" ++ f a ++ ")" 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-13
    • 1970-01-01
    • 2015-02-24
    • 1970-01-01
    • 2021-11-29
    • 2023-03-15
    • 2012-11-18
    相关资源
    最近更新 更多