haskell “show”记录,不派生Show

pvabu6sv  于 2023-10-19  发布在  其他
关注(0)|答案(4)|浏览(116)

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

k97glaaz

k97glaaz1#

独立派生

类型定义上的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:force

您可以在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手册中的 * 断点和检查变量 *。

zfciruhq

zfciruhq2#

如果你想以任何方式打印它,你必须让你的数据类型成为Show的示例。如果你不想派生Show,你可以自己实现它。

data Foo = Bar

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

main = print f where f = Bar
flseospp

flseospp3#

你完全可以打印没有Show示例的东西。

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

7gyucuyw4#

我有很多带类型参数的深度函数,比如n(用于数字类型),但函数上没有Show n约束。这个函数最终被类似Double的东西调用。
要查看值而不对函数及其所有依赖项添加Show约束,可以使用以下命令:

forceTraceShowId :: forall a b. Show b => a -> a
forceTraceShowId x = trace (show $ unsafeCoerce @a @b x) x

并像forceTraceShowId @_ @Double一样调用forceTraceShowId
或者,您可以在所需的行/函数处设置断点,并在运行时使用:force x显示变量x的值

相关问题