Proposal: Improve error messages for (!!) (include index and length of list)

Simon Hengel sol at typeful.net
Thu Oct 16 06:20:55 UTC 2014


Hi,
currently we have the following implementation for (!!):

    #ifdef USE_REPORT_PRELUDE
    xs     !! n | n < 0 =  error "Prelude.!!: negative index"
    []     !! _         =  error "Prelude.!!: index too large"
    (x:_)  !! 0         =  x
    (_:xs) !! n         =  xs !! (n-1)
    #else
    -- HBC version (stolen), then unboxified
    xs !! (I# n0) | isTrue# (n0 <# 0#) =  error "Prelude.(!!): negative index\n"
                  | otherwise          =  sub xs n0
                             where
                                sub :: [a] -> Int# -> a
                                sub []     _ = error "Prelude.(!!): index too large\n"
                                sub (y:ys) n = if isTrue# (n ==# 0#)
                                               then y
                                               else sub ys (n -# 1#)
    #endif

I propose to change the error messages for the non-report version to
include index and list length, something that is functionally equivalent
to:

    xs !! (I# n0) | isTrue# (n0 <# 0#) =  indexError xs n0
                  | otherwise          =  sub xs n0
                             where

                                sub :: [a] -> Int# -> a
                                sub []     _ = indexError xs n0
                                sub (y:ys) n = if isTrue# (n ==# 0#)
                                               then y
                                               else sub ys (n -# 1#)
    indexError :: [a] -> Int# -> b
    indexError xs (I# -> n)
      | n < 0 = error ("Prelude.(!!): negative index " ++ show n)
      | otherwise = error ("Prelude.(!!): index " ++ show n ++ " too large for list of length " ++ show (length xs))

Some usage examples:

    *Main> [1, 2, 3] !! (-1)
    *** Exception: Prelude.(!!): negative index -1
    *Main> [1, 2, 3] !! 3
    *** Exception: Prelude.(!!): index 3 too large for list of length 3

This will require some refactoring, i.e. we need to move itos from
GHC.Show to e.g. GHC.Base.

Discussion period: 2 weeks

Cheers,
Simon


More information about the Libraries mailing list