10

我目前正在處理一些我沒有寫的Haskell代碼,但是我已經做了修改。我的變化後,我運行程序並得到以下錯誤消息:我可以使用OverlappingInstances獲取更好的錯誤消息嗎?

Prelude.!!: index too large 

!!的調用是不是在我的代碼,所以重構它帶走更多的工作比我想做的事,如果我能避免它。

我想什麼是做這樣的事情:

class PrintList a where 
    (!!) :: [a] -> Int -> a 

instance (Show a) => PrintList a where 
    l (!!) n = if n < (length l) 
      then (l Prelude.!! n) 
      else error ("Index " ++ show n ++ " out of bounds in " ++ show l) 

instance PrintList a where 
    (!!) = Prelude.!! 

即功能!!爲每一個可能的列表類型定義,但它的行爲有所不同,每當一個顯示實例元素類型定義。

或者,tryShow :: a -> Maybe String方法也做的伎倆。

有沒有辦法做到這一點?只有當Show實現不適用時,我才能強制OverlappingInstances使用默認實現嗎?這是保證行爲嗎?

編輯:獎勵積分的人誰可以得到錯誤同時打印一個堆棧跟蹤般的消息!

回答

8

你不需要重疊的情況下,只需使用GHC調試你自己(!!)

{-# OPTIONS -Wall -O0 #-} 
module Debugger3 where 

import qualified Prelude as P 
import Prelude hiding ((!!)) 

(!!) :: [a] -> Int -> a 
xs !! n = 
    xs P.!! n -- line 9 

foo :: Int -> Int 
foo n = [0..n] !! 3 

bar :: Int -> Int 
bar n = foo (n-3) 

main :: IO() 
main = print (bar 4) 

GHCI會議:

> :l Debugger3 
[1 of 1] Compiling Debugger3  (Debugger3.hs, interpreted) 
Ok, modules loaded: Debugger3. 
*Debugger3> :break 9 
Breakpoint 1 activated at Debugger3.hs:9:4-18 
*Debugger3> :trace main 
Stopped at Debugger3.hs:9:4-18 
_result :: a = _ 
n :: Int = 3 
xs :: [a] = _ 
[Debugger3.hs:9:4-18] *Debugger3> :force xs 
xs = [0,1] 
[Debugger3.hs:9:4-18] *Debugger3> :history 
-1 : !! (Debugger3.hs:(8,1)-(9,18)) 
-2 : foo (Debugger3.hs:12:9-19) 
-3 : foo (Debugger3.hs:12:1-19) 
-4 : bar (Debugger3.hs:15:9-17) 
-5 : bar (Debugger3.hs:15:1-17) 
-6 : main (Debugger3.hs:18:15-19) 
-7 : main (Debugger3.hs:18:8-20) 
<end of history> 
[Debugger3.hs:9:4-18] *Debugger3> :back 
Logged breakpoint at Debugger3.hs:(8,1)-(9,18) 
_result :: a 
[-1: Debugger3.hs:(8,1)-(9,18)] *Debugger3> :back 
Logged breakpoint at Debugger3.hs:12:9-19 
_result :: Int 
n :: Int 
[-2: Debugger3.hs:12:9-19] *Debugger3> n 
1 
+0

這非常好,肯定是 「真實世界」回答。但我仍然喜歡看看是否有辦法獲得我正在談論的實例行爲。 – jmite

相關問題