fork download
  1. import Control.Monad
  2. import GHC.Base (build)
  3.  
  4. data Tree a
  5. = Nil
  6. | Branch !a (Tree a) (Tree a)
  7. deriving (Show, Eq)
  8.  
  9. foldrNotEach :: (Tree Bool -> b -> b) -> b -> Tree Bool -> b
  10. foldrNotEach f init (Branch x l r) =
  11. Branch (not $! x) l r `f`
  12. foldrNotEach
  13. (\l' -> f (Branch x l' r))
  14. (foldrNotEach (\r' -> f (Branch x l r')) init r)
  15. l
  16. foldrNotEach _ init Nil = init
  17. {-# SPECIALIZE foldrNotEach :: (Tree Bool -> [Tree Bool] -> [Tree Bool]) -> [Tree Bool] -> Tree Bool -> [Tree Bool] #-}
  18.  
  19. notEach :: Tree Bool -> [Tree Bool]
  20. notEach t = build (\c n -> foldrNotEach c n t)
  21. {-# INLINE[0] notEach #-}
  22.  
  23. procreateL :: Int -> Tree Bool
  24. procreateL 0 = Nil
  25. procreateL n = Branch (n `rem` 2 == 0) (procreateL (n - 1)) (procreateL (n `div` 2))
  26.  
  27. procreateR :: Int -> Tree Bool
  28. procreateR 0 = Nil
  29. procreateR n = Branch (n `rem` 2 == 0) (procreateR (n `div` 2)) (procreateR (n - 1))
  30.  
  31. test :: IO ()
  32. test = do
  33. guard $ notEach (procreateL 3) == [Branch True (Branch True (Branch False Nil Nil) (Branch False Nil Nil)) (Branch False Nil Nil),Branch False (Branch False (Branch False Nil Nil) (Branch False Nil Nil)) (Branch False Nil Nil),Branch False (Branch True (Branch True Nil Nil) (Branch False Nil Nil)) (Branch False Nil Nil),Branch False (Branch True (Branch False Nil Nil) (Branch True Nil Nil)) (Branch False Nil Nil),Branch False (Branch True (Branch False Nil Nil) (Branch False Nil Nil)) (Branch True Nil Nil)]
  34. guard $ notEach (procreateR 3) == [Branch True (Branch False Nil Nil) (Branch True (Branch False Nil Nil) (Branch False Nil Nil)),Branch False (Branch True Nil Nil) (Branch True (Branch False Nil Nil) (Branch False Nil Nil)),Branch False (Branch False Nil Nil) (Branch False (Branch False Nil Nil) (Branch False Nil Nil)),Branch False (Branch False Nil Nil) (Branch True (Branch True Nil Nil) (Branch False Nil Nil)),Branch False (Branch False Nil Nil) (Branch True (Branch False Nil Nil) (Branch True Nil Nil))]
  35. guard $ length (notEach $ procreateL 150) == 1564307
  36. guard $ length (notEach $ procreateR 150) == 1564307
  37.  
  38. main = test
Success #stdin #stdout 1.12s 86296KB
stdin
Standard input is empty
stdout
Standard output is empty