4
假設我有這樣的數據類型:哈斯克爾:如何漂亮的打印不帶引號的字符串?
data SomeDataType a = SomeDataType a
我想表明其對用戶(在控制檯輸出)表示,所以我需要一個「漂亮打印」功能。我不想使用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
在這一點上,我懷疑有一種完全不同的方法來解決這個「漂亮的打印」問題。是這樣嗎?或者我在代碼中遺漏了一些簡單明顯的錯誤?