2009-07-20 41 views
4

我想用Debug.Trace.trace打印一些我知道的是Show。就像我在Python做等Haskell:任何debugShow函數?

一種解決方案是增加「Show a =>」的地方,我希望把跟蹤功能的簽名,以及任何函數調用它,等

但如果我可以使用debugShow函數調用show(如果該值爲1),則返回值會更好,否則返回"--no show--"或其他值。

這是我失敗的嘗試定義DebugShow(GHC拒絕"Duplicate instance declarations"):

{-# LANGUAGE FlexibleInstances, UndecidableInstances, OverlappingInstances #-} 

class DebugShow a where 
    debugShow :: a -> String 

instance Show a => DebugShow a where 
    debugShow = show 

instance DebugShow a where 
    debugShow = const "--no show--" 

某種「不安全投」也能解決我的問題。

有什麼建議嗎?

注 - 這僅用於調試目的。我沒有在任何完成的代碼中使用它。

回答

3

我並不完全確定這一點,但我認爲這是不可能的,如果不在使用站點和每個類型變量確定的調用站點之間的整個調用鏈中添加類上下文。原因是可操作的:至少在GHC中,每個類都由一個字典來實現。因此,在使用的網站,我們需要一個Show字典a,如果有的話。但爲了得到這個,我們需要它從已確定的網站a傳遞下來,這就需要在所有中間函數的簽名中加入一些東西。

1

「不安全的演員」被稱爲unsafeCoerce。請注意其documentation中的警告;這是導致崩潰和其他犯規行爲的簡單方法。

+0

@ephemient:謝謝。在這種情況下,我似乎可以使用'unsafeCoerce'來「投射」到一個特定的類型,但我想將它「投射」到相同的未知類型並在其上下文中添加「Show」。我試圖定義「`debugShow = show。unsafeCoerce`」,但是因爲「`Ambiguous type variable`」而失敗了。「 – yairchu 2009-07-20 16:31:13

4

也許你想的一些變種:

traceShow :: (Show a) => a -> b -> b 
traceShow = trace . show 

在Debug.Trace

約束定義的「來電秀如果該值有一個,否則返回‘--no show--’什麼「是一個難題。我認爲,您需要重疊(和不連貫)的實例來爲所有類型定義一個默認的Show(可能通過unsafeCoerce或真空)。

+0

@dons:當你通過真空說,你是什麼意思?這是一種說不能做到的方式嗎? – yairchu 2009-07-21 08:17:05

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