Improve some Foldable methods for NonEmpty

Authored by dfeuer on May 8 2018, 7:38 PM.


  • length is improved by using the default definition, while foldr1 is improved by using a custom one.
  • Several methods had useless lazy pattern matches (i.e., the functions were actually strict in those arguments). Remove ~s to clarify.

Diff Detail

rGHC Glasgow Haskell Compiler
Automatic diff as part of commit; lint not applicable.
Automatic diff as part of commit; unit tests not applicable.
dfeuer created this revision.May 8 2018, 7:38 PM
ygale added a subscriber: ygale.May 9 2018, 6:25 AM

I have alternative patch, but I don't know how to do that on Phab, sorry, For now I pasted it in a comment in the Trac ticket.

bgamari added a comment.EditedMay 13 2018, 10:00 AM

I quickly checked in a standalone module and it looks to me like length on NonEmpty does not fuse (neither before nor after this patch). Do you have any insight into why this might be?

{-# LANGUAGE BangPatterns #-}

import Data.Foldable as F
import Data.List.NonEmpty

xs = 1 :| [2,3,4,5]
ys = [2,3,4,5]

foldr1 f (p :| ps) = foldr go id ps p
    go x r prev = f prev (r x)

length' xs = foldr lengthFB idLength xs 0

{-# INLINE [0] lengthFB #-}
lengthFB :: x -> (Int -> Int) -> Int -> Int
lengthFB _ r = \ !a -> r (a + 1)

{-# INLINE [0] idLength #-}
idLength :: Int -> Int
idLength = id

main = do 
    --print $ length' xs
    print $ F.length xs
    --print $ F.length ys
bgamari accepted this revision.May 13 2018, 10:00 AM

Otherwise looks good to me.

This revision is now accepted and ready to land.May 13 2018, 10:00 AM

There are several things that don't fuse here. I'm not sure why as yet, but the unfoldings seem to get optimized too much. I think we can address that separately.

This revision was automatically updated to reflect the committed changes.