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

David Feuer david.feuer at gmail.com
Thu Oct 16 06:40:41 UTC 2014


I'm generally +1 on this concept, but I'd like to see some evidence that
there is no measurable performance impact on nofib and perhaps also other
benchmarks, particularly for very short ephemeral lists. Note that saving
the index requires actually putting it somewhere.
On Oct 16, 2014 2:21 AM, "Simon Hengel" <sol at typeful.net> wrote:

> 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
> _______________________________________________
> Libraries mailing list
> Libraries at haskell.org
> http://www.haskell.org/mailman/listinfo/libraries
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/libraries/attachments/20141016/990bb648/attachment.html>


More information about the Libraries mailing list