Guest User

Untitled

a guest
Feb 18th, 2018
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.03 KB | None | 0 0
  1. module SuccGroups where
  2.  
  3. import Control.Arrow ((&&&), first)
  4. import Data.Function (on)
  5. import Data.List
  6.  
  7. -- | Given two enumerable values, test whether the latter is the successor of
  8. -- the former.
  9.  
  10. enumSucc :: (Enum a, Eq a) => a -> a -> Bool
  11. enumSucc a b = succ a == b
  12.  
  13. -- | Return the starting index and the length of the item returned by succSpans
  14. -- with the highest length.
  15. --
  16. -- Given [0,1,10,11,12,14,20,21] and the predicate enumSucc, return (2,3).
  17.  
  18. maxSuccBy :: (a -> a -> Bool) -> [a] -> (Integer, Integer)
  19. maxSuccBy p = maximumBy (compare `on` snd) . succSpansBy p
  20.  
  21. -- | Return the starting indices and the lengths of the sublists returned by
  22. -- succGroupIndBy.
  23. --
  24. -- Given [0,1,10,11,12,14,20,21] and the predicate enumSucc, return
  25. -- [(0,2),(2,3),(5,1),(6,2)].
  26.  
  27. succSpansBy :: (a -> a -> Bool) -> [a] -> [(Integer, Integer)]
  28. succSpansBy p = map (fst . head &&& genericLength) . succGroupIndBy p
  29.  
  30. -- | Zip the input list with indices and call succGroupBy with the predicate p
  31. -- on the original, pre-zip value.
  32. --
  33. -- Given [0,1,10,11,12,14,20,21] and the predicate enumSucc, return
  34. -- [[(0,0),(1,1)], [(2,10),(3,11),(4,12)], [(5,14)], [(6,20),(7,21)]].
  35.  
  36. succGroupIndBy :: (a -> a -> Bool) -> [a] -> [[(Integer, a)]]
  37. succGroupIndBy p = succGroupBy (p `on` snd) . zip [0..]
  38.  
  39. -- | Return the groups of those items where each pair matches the predicate p.
  40. --
  41. -- Given [0,1,10,11,12,14,20,21] and the predicate enumSucc, return [[0,1],
  42. -- [10,11,12], [14], [20,21]].
  43.  
  44. succGroupBy :: (a -> a -> Bool) -> [a] -> [[a]]
  45. succGroupBy p xs@(_:_) = as:succGroupBy p bs
  46. where (as, bs) = succSpanBy p xs
  47. succGroupBy _ [] = []
  48.  
  49. -- | Return (as,bs) where as is the list of those items where each pair matches
  50. -- the predicate p and bs is the rest of the list.
  51. --
  52. -- Given [0,1,10,11,12,14,20,21] and the predicate enumSucc, return
  53. -- ([0,1], [10,11,12,14,20,21]).
  54.  
  55. succSpanBy :: (a -> a -> Bool) -> [a] -> ([a], [a])
  56. succSpanBy p (x0:xs@(x1:_))
  57. | p x0 x1 = first (x0:) . succSpanBy p $ xs
  58. | otherwise = ([x0], xs)
  59. succSpanBy _ xs@[_] = (xs, [])
  60. succSpanBy _ [] = ([], [])
Add Comment
Please, Sign In to add comment