Haskell:如何漂亮地打印不带引号的字符串?

标签 haskell pretty-print

假设我有这种数据类型:

data SomeDataType a = SomeDataType a

我想向用户展示它的表示(在控制台输出中),所以我需要一个“ pretty-print ”功能。我不想使用 show ,因为它将返回一个表达式,我只想将我的类型的唯一字段的值转换为字符串。

我期望这种行为:
>>> let myintdata = SomeDataType (22::Int)
>>> putStrLn $ prettyPrint myintdata
22
>>> let alice = SomeDataType "Alice"
>>> let bob = SomeDataType "Bob"
>>> putStrLn $ prettyPrint alice ++ " loves " ++ prettyPrint bob
Alice loves Bob

所以我像这样实现它:
prettyPrint :: Show a => SomeDataType a -> String
prettyPrint (SomeDataType x) = show x

它适用于数字,但字符串被引用和转义:
>>> let alice = SomeDataType "Alice"
>>> let bob = SomeDataType "Bob"
>>> putStrLn $ prettyPrint alice ++ " loves " ++ prettyPrint bob
"Alice" loves "Bob"

此外,我希望完全控制将来如何将不同的内容类型转换为字符串。所以,我要创建自己的类型类了!它是这样的:
{-# LANGUAGE FlexibleInstances #-}

data SomeDataType a = SomeDataType a

class PrettyPrint a where
    prettyPrint :: a -> String

instance {-# OVERLAPPABLE #-} PrettyPrint a where
    -- I don't care about this right now,
    -- let's learn how to print strings without quotes first!
    prettyPrint = const "Stupid Robot" 

instance PrettyPrint String where
    prettyPrint = id

instance Show a => PrettyPrint (SomeDataType a) where
    prettyPrint (SomeDataType x) = prettyPrint x

我对第一次测试很满意:
>>> putStrLn $ prettyPrint "No quotes!"
No quotes!

但是当我试图漂亮地打印我的数据类型时,会以某种方式调用通用实例而不是字符串:
>>> let alice = SomeDataType "Alice"
>>> let bob = SomeDataType "Bob"
>>> putStrLn $ prettyPrint alice ++ " loves " ++ prettyPrint bob
Stupid Robot loves Stupid Robot

在这一点上,我怀疑有一种完全不同的方法来解决这个“ pretty-print ”问题。是这样吗?还是我在代码中遗漏了一些简单而明显的错误?

最佳答案

在最后一个例子中,您假设 Show a并且编译器仅使用此信息为 prettyPrint x 选择合适的实例.

您可以通过要求 PrettyPrint a 添加更多信息作为基类:

instance PrettyPrint a => PrettyPrint (SomeDataType a) where
    prettyPrint (SomeDataType x) = prettyPrint x

关于Haskell:如何漂亮地打印不带引号的字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34626405/

相关文章:

haskell - 这个语法在 Haskell 中是什么意思 : _|_ or (_|_)

haskell - printf 字符串列表

vba - 如何漂亮地打印VBA代码?

python - 在混合类型的嵌套元组中打印格式化 float

c++ - C++代码最好的prettyprint选项是什么?

Java:如何漂亮地打印 .java 文件

asp.net - Visual Studio ASP.NET/HTML 重新格式化功能 - 它存在吗?

haskell - Haskell 是否有类似于后期绑定(bind)的东西(或者,我们可以更改正在进行的 Haskell 程序的功能定义)吗?

haskell - 允许数据构造函数的多个声明

haskell - Haskell 中的泛型函数...我不明白 :(