fork(1) download
  1. {-# LANGUAGE MultiParamTypeClasses #-}
  2. {-# LANGUAGE FlexibleInstances #-}
  3. {-# LANGUAGE OverlappingInstances #-}
  4.  
  5. class Space a b where
  6. slice :: a -> ([b], a)
  7.  
  8. instance Space [a] a where
  9. slice (l:ls) = ([l], ls)
  10. slice [] = ([], [])
  11.  
  12. instance (Space sp x) => Space ([sp], [sp]) x where
  13. slice (fs, b:bs) = let
  14. ss = map slice (b : fs)
  15. yield = concat $ map fst ss
  16. in (yield, (map snd ss, bs))
  17.  
  18. enumerate :: (Space sp x) => sp -> [x]
  19. enumerate sp = let (sl, sp') = slice sp
  20. in sl ++ enumerate sp'
  21.  
  22. main = do
  23. let l1 = [0..] :: [Int]
  24. let ss1 = enumerate l1 :: [Int]
  25. print $ take 10 ss1
  26.  
  27. let l2 = ([], map (\i -> map ((,) i) [0..]) [0..]) :: ([[(Int, Int)]], [[(Int, Int)]])
  28. let ss2 = enumerate l2 :: [(Int, Int)]
  29. print $ take 10 ss2
  30.  
  31. let l3 = ([], map (\i -> ([], map (\j -> map ((,,) j i) [0..]) [0..])) [0..]) :: ([([[(Int, Int, Int)]], [[(Int, Int, Int)]])], [([[(Int, Int, Int)]], [[(Int, Int, Int)]])])
  32. let ss3 = enumerate l3 :: [(Int, Int, Int)]
  33. print $ take 10 ss3
  34.  
Success #stdin #stdout 0s 6232KB
stdin
Standard input is empty
stdout
[0,1,2,3,4,5,6,7,8,9]
[(0,0),(1,0),(0,1),(2,0),(1,1),(0,2),(3,0),(2,1),(1,2),(0,3)]
[(0,0,0),(0,1,0),(1,0,0),(0,0,1),(0,2,0),(1,1,0),(0,1,1),(2,0,0),(1,0,1),(0,0,2)]