我想使用Debug.Trace.trace
打印我知道的Show
内容。就像我在Python等中所做的那样。
一种解决方案是将“Show a =>
”添加到我想要跟踪的函数的签名,以及调用它的任何函数等。
但如果我可以使用一些调用debugShow
的{{1}}函数,如果值为1,则会更好,否则会返回show
或其他内容。
这是我尝试定义"--no show--"
失败的尝试(GHC拒绝DebugShow
):
"Duplicate instance declarations"
某种“不安全的演员”也会解决我的问题。
有什么建议吗?
注意 - 这仅用于调试目的。我没有在任何完成的代码中使用它。
答案 0 :(得分:4)
也许你想要一些变体:
traceShow :: (Show a) => a -> b -> b
traceShow = trace . show
在Debug.Trace中定义
约束“调用显示值是否有一个,否则返回”--no show--“或者”是一个很难的东西。我认为,您需要重叠(和不连贯)实例来定义所有类型的默认显示(可能通过unsafeCoerce,或通过真空)。
答案 1 :(得分:3)
我并不完全确定这一点,但我认为如果没有在使用站点和确定每个类型变量的调用站点之间的整个调用链中添加类上下文,这是不可能的。其原因是可操作的:至少在GHC中,每个类都是由字典实现的。因此,在使用网站上,如果存在Show
a
,我们需要一个a
字典。但要实现这一点,我们需要将它从已确定{{1}}的站点传递下来,这需要在所有中间函数的签名中使用。
答案 2 :(得分:1)
“不安全演员”被称为unsafeCoerce
。请注意documentation中的警告;这是导致崩溃和其他犯规行为的简单方法。
答案 3 :(得分:0)
只需在DebugShow类中使用默认方法实现。这应该完全符合您的要求:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
class DebugShow a where
debugShow :: a -> String
debugShow = const "--no show--"
instance Show a => DebugShow a where
debugShow = show