Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are there two definitions of init function in Prelude?

Tags:

haskell

I found in Prelude two definitions of the function init:

init [x] = []
init (x:xs) = x : init xs
init [] = errorEmptyList "init"

init [] = errorEmptyList "init"
init (x:xs) = init' x xs
  where init' _ [] = []
        init' y (z:zs) = y : init' z zs

What is the reason of the second definition?

like image 397
allmass Avatar asked Mar 15 '19 13:03

allmass


1 Answers

You haven't quoted it verbatim. It's actually:

-- | Return all the elements of a list except the last one.
-- The list must be non-empty.
init                    :: [a] -> [a]
#if defined(USE_REPORT_PRELUDE)
init [x]                =  []
init (x:xs)             =  x : init xs
init []                 =  errorEmptyList "init"
#else
-- eliminate repeated cases
init []                 =  errorEmptyList "init"
init (x:xs)             =  init' x xs
  where init' _ []     = []
        init' y (z:zs) = y : init' z zs
#endif

The USE_REPORT_PRELUDE means that this piece of code adheres to Haskell Report, while the other one is a potentially more efficient implementation. Check out this thread for similar discussion about reverse.

like image 70
Bartek Banachewicz Avatar answered Nov 07 '22 14:11

Bartek Banachewicz