QuadraticImportOneData.hs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. {-# LANGUAGE LambdaCase #-}
  2. -- | Create a sequence of files each of which imports all previous ones
  3. -- and defines one data type and an alias for its only constructor.
  4. --
  5. -- @
  6. -- module FileNNN where
  7. --
  8. -- import File000
  9. -- ...
  10. -- import File(NNN-1)
  11. --
  12. -- data D : Set where c : D
  13. --
  14. -- test : D
  15. -- test = c
  16. -- @
  17. import Control.Monad (forM_)
  18. import System.Directory (createDirectoryIfMissing)
  19. import System.Environment (getArgs, getProgName)
  20. import System.FilePath ((</>), (<.>))
  21. import Text.Read (readMaybe)
  22. filePrefix = "File"
  23. mainName = "Main"
  24. main :: IO ()
  25. main = do
  26. getArgs >>= \case
  27. [dir, s] | Just n <- readMaybe s -> run dir n
  28. _ -> usage
  29. usage :: IO ()
  30. usage = do
  31. me <- getProgName
  32. putStr $ unlines
  33. [ unwords [ "usage:", me, "DIRECTORY", "NUM" ]
  34. , "Creates in directory DIRECTORY NUM files named " ++ filePrefix ++ "XXX.agda,"
  35. , "each importing all previous ones, plus a file named " ++ mainName ++ ".agda,"
  36. , "importing all the other files."
  37. ]
  38. run
  39. :: FilePath -- ^ Directory in which to create the files.
  40. -> Int -- ^ Number of files to create.
  41. -> IO ()
  42. run dir n = do
  43. createDirectoryIfMissing True dir
  44. -- Create files
  45. forM_ [0..n-1] $ \ i -> do
  46. let fileName = (filePrefix ++ print0d w i) <.> "agda"
  47. writeFile (dir </> fileName) $ createContent n i
  48. -- Create main file
  49. writeFile (dir </> "Main" <.> "agda") $ createMainContent n
  50. where
  51. w = length $ show n
  52. -- | Created content of main file, importing the others.
  53. createMainContent
  54. :: Int -- ^ Number of files we create.
  55. -> String -- ^ Content.
  56. createMainContent n = unlines $ concat
  57. [ map (\ j -> "import " ++ filePrefix ++ print0d w j) [0..n-1]
  58. ]
  59. where
  60. w = length $ show n
  61. -- | Create list of strings containing:
  62. -- @
  63. -- module FileNNN where
  64. --
  65. -- import File000
  66. -- ...
  67. -- import File(NNN-1)
  68. --
  69. -- data D : Set where c : D
  70. --
  71. -- test : D
  72. -- test = c
  73. -- @
  74. createContent
  75. :: Int -- ^ Number of files we create.
  76. -> Int -- ^ Number of the file we create here.
  77. -> String -- ^ Content.
  78. createContent n i = unlines $ concat
  79. [ [ unwords [ "module" , filePrefix ++ print0d w i, "where" ]
  80. , ""
  81. ]
  82. , map (\ j -> "import " ++ filePrefix ++ print0d w j) [0..i-1]
  83. , [ ""
  84. , "data D : Set where c : D"
  85. , ""
  86. , "test : D"
  87. , "test = c"
  88. ]
  89. ]
  90. where
  91. w = length $ show n
  92. -- | Equivalent to @sprintf("%0<width>d", num)@
  93. print0d
  94. :: Int -- ^ Width.
  95. -> Int -- ^ Print this integer.
  96. -> String -- ^ Padded from the left with 0s.
  97. print0d w i = pad ++ s
  98. where
  99. s = show i
  100. pad = replicate (w - length s) '0'