I'm currently dealing with some Haskell code that I didn't write, but that I've made changes to. After my changes, I run the program and get the following error message:
Prelude.!!: index too large
The call to !!
is not in my code, so refactoring it away is more work than I want to do, if I can avoid it.
What I'd like is to do something like this:
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.!!
i.e. the function !!
is defined for every possible list type, but it behaves differently whenever a Show instance is defined for the element type.
Alternately, a tryShow :: a -> Maybe String
method would also do the trick.
Is there a way to do this? Can I force OverlappingInstances to use the default implementation only when the Show implementation does not apply? Is this guaranteed behaviour?
EDIT: bonus points for anyone who can get the error to also print a stack-trace-like message!
You don't need overlapping instances, just use the GHC debugger on your own (!!)
:
{-# 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 session:
> :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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With