├── .WolframResources ├── .gitignore ├── .project ├── LICENSE ├── README.md ├── VerificationTests.nb ├── VerificationTests.wlt ├── lazyLists-1.0.paclet ├── lazyLists.nb └── lazyLists ├── Kernel ├── DefaultsAndMessages.wl ├── UsageMessages.wl ├── lazyConstructors.wl ├── lazyLists.wl ├── lazySyntacticSugar.wl ├── lazyTuples.wl └── partitionedLazyLists.wl └── PacletInfo.wl /.WolframResources: -------------------------------------------------------------------------------- 1 | Resources[ 2 | Version[1], 3 | ExecutionBuildCommand["< 2 | 3 | lazyLists 4 | 5 | 6 | 7 | 8 | 9 | com.wolfram.eclipse.MEET.MathematicaProjectBuilder 10 | 11 | 12 | 13 | 14 | 15 | com.wolfram.eclipse.MEET.SimpleMathematicaNature 16 | 17 | 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Sjoerd Smit 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # lazyLists package for Wolfram Language 2 | 3 | Implements Haskell-style lazy lists in Mathematica and adds syntactic sugar to various build-in functions to work with them. Lazylists make it possible to iterate through large amounts of data without holding it all in memory at once and even allow for potentially infinite lists (e.g., the list of all integers) to be used in computations. 4 | 5 | ## Installation instructions 6 | 7 | 1. Clone the repository or download the ZIP and unzip in a directory of choice 8 | 2. You can start using the code by opening the file lazyLists.nb and running the intialisation lines at the top 9 | 3. If, instead, you want to use the code from another notebook, just point the Paclet Manager at the right directory (i.e., the directory of lazyLists.nb) with `PacletDirectoryLoad` (`PacletDirectoryAdd` in versions <= 12.0) to and then run: 10 | 11 | << lazyLists` 12 | 13 | 4. If you want to install the package as a Wolfram Paclet so that you can `Get` it from anywhere you only need to download the .paclet file and run: 14 | 15 | PacletInstall["path/to/lazyLists-X.X.paclet"] 16 | 17 | 18 | ## Using the code 19 | 20 | See lazyLists.nb for details and examples. 21 | 22 | 23 | ## Change log 24 | 25 | * 21 September 2018: 26 | * Add `lazyTuples`, which is the lazy version of `Tuples`. Includes helper functions for generating tuples efficiently. 27 | * Hotfix: `lazyTuples` will now switch between compiled evaluation and regular evaluation depending on the size of the integers involves (since `Compile` can only use machine numbers). 28 | * 22 September 2018 29 | * Add `partWhile`, which finds the last element in a lazyList that matches a selector function. Also add support for `Part[lz, {-1}]`, which is equivalent to `partWhile[lz, True&]`. 30 | * Add `Take[lz, All]` as usable syntax for finite lazyLists. 31 | * 23 September 2018 32 | * Add `lazyCatenate`, which works like regular `Catenate` but returns a lazyList. Works on lists and lazyLists or any mixture of the two. 33 | * Add `FoldPairList` as supported system symbol. 34 | * Add `Prepend` and `Append` as usable system symbols. Also add `lazyPrependTo` and `lazyAppendTo` to modify lazyLists created by `lazyList[Hold[var]]`. 35 | * Add use case `lazyTuples[n]`, which gives an infinite lazyList that generates all n-tuples of positive integers iteratively. 36 | * 24 September 2018 37 | * Add `setLazyListable`, which is used to set a pseudo-Listable attribute to symbols that makes them automatically thread over lazyLists. 38 | * Add partitioned lazyLists. Any lazyList that generates ordinary lists can be converted to a `partitionedLazyList`. Doing so effectively flattens the generated lists into one continuous list. `partitionedLazyList` supports list operations like `Map` and `Fold`, which will be applied directly to the generated lists for efficiency. 39 | * 25 September 2018 40 | * Add `{start, stop, step}` syntax for `Take`, which can be used in conjunction with `partitionedLazyList`. 41 | * Some efficiency updates to `Take` and `Part`. 42 | * Add `lazyMapThread` and `lazyCatenate` for `partitionedLazyList`. 43 | * Add `lazyPartition`, which can be used to make a `partitionedLazyList` out of any normal `lazyList`. 44 | * Implement pseudo-listability for `partitionedLazyList`. 45 | * 26 September 2018 46 | * Various updates to `partitionedLazyList` to bring it more in line with ordinary `lazyList`. 47 | * Re-implement `lazyTuples` using `partitionedLazyList` to make tuples generation significantly faster. 48 | * 28 September 2018 49 | * Implement `LengthWhile` for `lazyList` and `partitionedLazyList`. Replaces `partWhile`, which was removed. 50 | * Add the `endOfLazyList` token, which is used to force lazy lists to terminate. 51 | * 19 April 2019 52 | * Update some matching patterns that technically should use `HoldPattern`. Clear all definition in the package when reloading it. 53 | * Test code in notebook in Mathematica V12. 54 | * 27 April 2019 55 | * Add new function `repartitionAll` which is used when threading over multiple `partitionedLazyList`s. 56 | * As a consequence, the `lazyListable` pseudo-attribute will now work with `partitionedLazyList`s that have been partitioned differently. 57 | * 07 May 2019 58 | * Add unit tests. 59 | * Fix dates in change log <_< 60 | * 20 May 2019 61 | * Add additional unit tests and add section in example notebook that shows how to run them. 62 | * 19 June 2019 63 | * Fix a bug where `endOfLazyList` wouldn't work if returned from a function mapped over a `lazyList`. 64 | * Add new function `composeMappedFunctions` which compacts multiple `Map`s into one. This was default behavior for `Map` before, but this feature was removed from `Map`. 65 | * 13 November 2019 66 | * Add support for using `Nothing` in `FoldList`. 67 | * 03 January 2020 68 | * Bring `lazyMapThread` in line with normal `MapThread`. 69 | * The code files have been restructured to match the specifications of a Wolfram Paclet. A Paclet installer has been added to the repository. 70 | * 22 July 2020 71 | * Add function `lazyTruncate` to cut long/infinite lazyLists short (without having to evaluate them fully). 72 | * Add support for held lists to `lazyMapThread`, `lazyTranspose` and `lazyCatenate`. 73 | * Add support for `TakeDrop`. 74 | * Add support for `Drop`. 75 | * 23 July 2020 76 | * Add function `lazyAggregate` that can be used to do running totals over large lists. 77 | * Add support for `AllTrue`, `AnyTrue` and `NoneTrue`. 78 | -------------------------------------------------------------------------------- /VerificationTests.wlt: -------------------------------------------------------------------------------- 1 | BeginTestSection["VerificationTests"] 2 | 3 | BeginTestSection["Initialisation"] 4 | 5 | VerificationTest[(* 1 *) 6 | CompoundExpression[Set[$HistoryLength, 10], With[List[Set[dir, If[Quiet[TrueQ[FileExistsQ[$TestFileName]]], DirectoryName[$TestFileName], NotebookDirectory[]]]], PacletDirectoryLoad[dir]], Quiet[Get["lazyLists`"]], ClearAll["Global`*"], "Done"] 7 | , 8 | "Done" 9 | , 10 | TestID->"429d6b44-7f18-408a-a11b-af3070fbdc57" 11 | ] 12 | 13 | EndTestSection[] 14 | 15 | BeginTestSection["Normal lazy lists"] 16 | 17 | BeginTestSection["Elementary tests"] 18 | 19 | VerificationTest[(* 2 *) 20 | lazyList[List[]] 21 | , 22 | lazyList[] 23 | , 24 | TestID->"0aa677fe-81d8-4776-8b22-218127c5e3f3" 25 | ] 26 | 27 | VerificationTest[(* 3 *) 28 | lazyList[Nothing, "stuff"] 29 | , 30 | "stuff" 31 | , 32 | TestID->"aab229e7-6fe6-4877-b94d-e6384e43ffe5" 33 | ] 34 | 35 | VerificationTest[(* 4 *) 36 | lazyList[Range[10]] 37 | , 38 | lazyList[1, lazyList[List[2, 3, 4, 5, 6, 7, 8, 9, 10]]] 39 | , 40 | TestID->"906af855-65d9-4a0f-8f45-8b9e50ea4bbe" 41 | ] 42 | 43 | EndTestSection[] 44 | 45 | BeginTestSection["lazyGenerator"] 46 | 47 | VerificationTest[(* 5 *) 48 | lazyGenerator[f] 49 | , 50 | lazyList[f[1], lazyLists`Private`twoSidedGenerator[f, Plus[1, 1], 1]] 51 | , 52 | TestID->"85cf9838-9b39-4011-816a-fcca14ff538a" 53 | ] 54 | 55 | VerificationTest[(* 6 *) 56 | lazyGenerator[f, 2] 57 | , 58 | lazyList[f[2], lazyLists`Private`twoSidedGenerator[f, Plus[2, 1], 1]] 59 | , 60 | TestID->"3327cab0-d7aa-4997-8b45-21e81e4fe2c8" 61 | ] 62 | 63 | VerificationTest[(* 7 *) 64 | lazyGenerator[f, 2, -1] 65 | , 66 | lazyList[f[2], lazyLists`Private`rightSidedGenerator[f, Plus[2, 1], -1, 1]] 67 | , 68 | TestID->"cc912d94-a5c6-499e-baf8-0d31abd12bc0" 69 | ] 70 | 71 | VerificationTest[(* 8 *) 72 | lazyGenerator[f, 2, 3] 73 | , 74 | lazyList[] 75 | , 76 | {lazyGenerator::badSpec} 77 | , 78 | TestID->"8d8a181a-232e-4002-832a-84251bae6c14" 79 | ] 80 | 81 | VerificationTest[(* 9 *) 82 | lazySetState[lazyGenerator[f, 2, -1], -1] 83 | , 84 | lazyList[f[-1], lazyLists`Private`rightSidedGenerator[f, Plus[-1, 1], -1, 1]] 85 | , 86 | TestID->"f984074f-5977-48f6-90ee-804563196302" 87 | ] 88 | 89 | VerificationTest[(* 10 *) 90 | lazySetState[lazyGenerator[f, 2, -1], -2] 91 | , 92 | lazyList[f[2], lazyLists`Private`rightSidedGenerator[f, Plus[2, 1], -1, 1]] 93 | , 94 | {Part::partw} 95 | , 96 | TestID->"e5c1e524-3ba2-43b0-b8f1-f27ba41461ce" 97 | ] 98 | 99 | VerificationTest[(* 11 *) 100 | lazyGenerator[f, 2, Times[-1, Infinity]] 101 | , 102 | lazyList[f[2], lazyLists`Private`twoSidedGenerator[f, Plus[2, 1], 1]] 103 | , 104 | TestID->"97b46cdb-8023-415c-8dd6-2ed4c695aa28" 105 | ] 106 | 107 | VerificationTest[(* 12 *) 108 | lazyGenerator[f, -1, Times[-1, Infinity], 3] 109 | , 110 | lazyList[f[-1], lazyLists`Private`leftSidedGenerator[f, Plus[-1, 1], 3, 1]] 111 | , 112 | TestID->"e1c956b5-2151-43f7-8b7e-5ff206119768" 113 | ] 114 | 115 | VerificationTest[(* 13 *) 116 | lazyGenerator[f, 4, Times[-1, Infinity], 3] 117 | , 118 | lazyList[] 119 | , 120 | {lazyGenerator::badSpec} 121 | , 122 | TestID->"8c7e86ea-620b-44ab-8aa2-db140ee35dc8" 123 | ] 124 | 125 | VerificationTest[(* 14 *) 126 | lazySetState[lazyGenerator[f, -1, Times[-1, Infinity], 3], 2] 127 | , 128 | lazyList[f[2], lazyLists`Private`leftSidedGenerator[f, Plus[2, 1], 3, 1]] 129 | , 130 | TestID->"98c938f6-fac2-4cc9-95fb-c832d1147566" 131 | ] 132 | 133 | VerificationTest[(* 15 *) 134 | lazySetState[lazyGenerator[f, -1, Times[-1, Infinity], 3], 4] 135 | , 136 | lazyList[f[-1], lazyLists`Private`leftSidedGenerator[f, Plus[-1, 1], 3, 1]] 137 | , 138 | {Part::partw} 139 | , 140 | TestID->"c916b38f-189f-4976-a05c-81f6f5de2fae" 141 | ] 142 | 143 | VerificationTest[(* 16 *) 144 | lazyGenerator[f, -1, -3, 3] 145 | , 146 | lazyList[f[-1], lazyLists`Private`finiteGenerator[f, Plus[-1, 1], -3, 3, 1]] 147 | , 148 | TestID->"3a1febb1-5752-484e-ab0e-9d9bb308b1aa" 149 | ] 150 | 151 | VerificationTest[(* 17 *) 152 | lazyGenerator[f, -4, -3, 3] 153 | , 154 | lazyList[] 155 | , 156 | {lazyGenerator::badSpec} 157 | , 158 | TestID->"da930bb9-74f3-4be8-adde-86d727d0db26" 159 | ] 160 | 161 | VerificationTest[(* 18 *) 162 | lazyGenerator[f, 4, -3, 3] 163 | , 164 | lazyList[] 165 | , 166 | {lazyGenerator::badSpec} 167 | , 168 | TestID->"8063f64e-dd4e-4afa-82ca-728521dba0e5" 169 | ] 170 | 171 | VerificationTest[(* 19 *) 172 | lazySetState[lazyGenerator[f, -1, -3, 3], 2] 173 | , 174 | lazyList[f[2], lazyLists`Private`finiteGenerator[f, Plus[2, 1], -3, 3, 1]] 175 | , 176 | TestID->"cbb5d08c-2a18-491c-abbb-c81f5dc99a56" 177 | ] 178 | 179 | VerificationTest[(* 20 *) 180 | lazySetState[lazyGenerator[f, -1, -3, 3], 4] 181 | , 182 | lazyList[f[-1], lazyLists`Private`finiteGenerator[f, Plus[-1, 1], -3, 3, 1]] 183 | , 184 | {Part::partw} 185 | , 186 | TestID->"4ba95654-41db-45e9-a5c3-e270b62d5e8c" 187 | ] 188 | 189 | VerificationTest[(* 21 *) 190 | lazySetState[lazyGenerator[f, -1, -3, 3], -4] 191 | , 192 | lazyList[f[-1], lazyLists`Private`finiteGenerator[f, Plus[-1, 1], -3, 3, 1]] 193 | , 194 | {Part::partw} 195 | , 196 | TestID->"ab0b420c-b3a3-4a33-9395-035ca9c2ada2" 197 | ] 198 | 199 | VerificationTest[(* 22 *) 200 | Set[symbolicGenerator, lazyGenerator[f, start, Times[-1, Infinity], Infinity, step]] 201 | , 202 | lazyList[f[start], lazyLists`Private`twoSidedGenerator[f, Plus[start, step], step]] 203 | , 204 | TestID->"e9ed830c-b556-4951-868b-db5959c367f7" 205 | ] 206 | 207 | VerificationTest[(* 23 *) 208 | First[symbolicGenerator] 209 | , 210 | f[start] 211 | , 212 | TestID->"03b84bb1-f51d-4db8-8121-cedb17db058e" 213 | ] 214 | 215 | VerificationTest[(* 24 *) 216 | Rest[symbolicGenerator] 217 | , 218 | lazyList[f[Plus[start, step]], lazyLists`Private`twoSidedGenerator[f, Plus[Plus[start, step], step], step]] 219 | , 220 | TestID->"ffc71697-2ed6-473e-9aa6-f1ab34671b59" 221 | ] 222 | 223 | VerificationTest[(* 25 *) 224 | Most[symbolicGenerator] 225 | , 226 | List[f[start]] 227 | , 228 | TestID->"b184721d-1ebf-4a52-b653-c207188109bf" 229 | ] 230 | 231 | VerificationTest[(* 26 *) 232 | Last[symbolicGenerator] 233 | , 234 | lazyList[f[Plus[start, step]], lazyLists`Private`twoSidedGenerator[f, Plus[Plus[start, step], step], step]] 235 | , 236 | TestID->"7c737812-143f-476b-a401-9e63785cb078" 237 | ] 238 | 239 | VerificationTest[(* 27 *) 240 | First[Take[symbolicGenerator, 5]] 241 | , 242 | List[f[start], f[Plus[start, step]], f[Plus[start, Times[2, step]]], f[Plus[start, Times[3, step]]], f[Plus[start, Times[4, step]]]] 243 | , 244 | TestID->"08ed6fb4-ba7e-4b2c-af71-c73815d1f2ae" 245 | ] 246 | 247 | VerificationTest[(* 28 *) 248 | First[Take[lazyGenerator[f, 2, 1, 10, 2], 50]] 249 | , 250 | List[f[2], f[4], f[6], f[8], f[10]] 251 | , 252 | TestID->"c1fb5cd2-752c-4f59-a9e0-1ccded5e3e9c" 253 | ] 254 | 255 | VerificationTest[(* 29 *) 256 | Take[lazyGenerator[f, 2, 1, 10, 2], All] 257 | , 258 | lazyList[List[f[2], f[4], f[6], f[8], f[10]], lazyList[]] 259 | , 260 | TestID->"e955f0bb-c384-4afa-86f8-e4a14194aab4" 261 | ] 262 | 263 | VerificationTest[(* 30 *) 264 | LengthWhile[lazyGenerator[f, 2, 1, 10, 2]] 265 | , 266 | Association[Rule["Index", 5], Rule["Element", lazyList[f[10], lazyList[]]]] 267 | , 268 | TestID->"aaba755e-f009-4647-9b80-513c0b1fbbc1" 269 | ] 270 | 271 | VerificationTest[(* 31 *) 272 | Part[lazyGenerator[f, 2, 1, 10, 2], List[-1]] 273 | , 274 | lazyList[f[10], lazyList[]] 275 | , 276 | TestID->"f1a60652-a2d1-4d3d-bd51-b266b6fb7327" 277 | ] 278 | 279 | VerificationTest[(* 32 *) 280 | Part[lazyGenerator[f, 2, 1, 10, 2], -1] 281 | , 282 | f[10] 283 | , 284 | TestID->"1a693f76-eb36-4d09-8805-38dc77a07a9d" 285 | ] 286 | 287 | VerificationTest[(* 33 *) 288 | Set[l, Take[lazyGenerator[f, 2, 1, 10, 2], 3]] 289 | , 290 | lazyList[List[f[2], f[4], f[6]], lazyLists`Private`finiteGenerator[f, Plus[6, 2], 1, 10, 2]] 291 | , 292 | TestID->"b37425f9-c20f-4f84-a718-f951063df8be" 293 | ] 294 | 295 | VerificationTest[(* 34 *) 296 | Take[lazySetState[Last[l], 3], 3] 297 | , 298 | lazyList[List[f[3], f[5], f[7]], lazyLists`Private`finiteGenerator[f, Plus[7, 2], 1, 10, 2]] 299 | , 300 | TestID->"0e297879-53fe-4b9e-8edc-e03241aabc38" 301 | ] 302 | 303 | VerificationTest[(* 35 *) 304 | First[lazySetState[lazyRange[start, step], newStart]] 305 | , 306 | newStart 307 | , 308 | TestID->"41a767ac-0948-486e-ad67-68276213a197" 309 | ] 310 | 311 | VerificationTest[(* 36 *) 312 | First[lazySetState[lazyPowerRange[start, r], newStart]] 313 | , 314 | newStart 315 | , 316 | TestID->"17271240-7711-4341-9f6b-d73ae952bafb" 317 | ] 318 | 319 | VerificationTest[(* 37 *) 320 | First[lazySetState[lazyNestList[f, start], newStart]] 321 | , 322 | newStart 323 | , 324 | TestID->"85d28eb3-0b69-4023-9a62-e0bca0fea29a" 325 | ] 326 | 327 | VerificationTest[(* 38 *) 328 | Set[infiniteInBothDirections, lazyGenerator[f]] 329 | , 330 | lazyList[f[1], lazyLists`Private`twoSidedGenerator[f, Plus[1, 1], 1]] 331 | , 332 | TestID->"7d510cd5-6253-419a-909d-b1a1b71cb108" 333 | ] 334 | 335 | VerificationTest[(* 39 *) 336 | First[Take[infiniteInBothDirections, 5]] 337 | , 338 | List[f[1], f[2], f[3], f[4], f[5]] 339 | , 340 | TestID->"82617601-f40e-481e-ab2e-33d645b93feb" 341 | ] 342 | 343 | EndTestSection[] 344 | 345 | BeginTestSection["lazyRange"] 346 | 347 | VerificationTest[(* 40 *) 348 | First[lazyRange[]] 349 | , 350 | 1 351 | , 352 | TestID->"5a25109e-e409-4241-87e2-2e902c6c5621" 353 | ] 354 | 355 | VerificationTest[(* 41 *) 356 | First[lazyRange[4]] 357 | , 358 | 4 359 | , 360 | TestID->"db625667-1aaa-4627-a9e3-474c84985890" 361 | ] 362 | 363 | VerificationTest[(* 42 *) 364 | First[lazyRange[4, 2]] 365 | , 366 | 4 367 | , 368 | TestID->"4bdbc2fc-4056-40de-8e7c-2bfa553ba08d" 369 | ] 370 | 371 | VerificationTest[(* 43 *) 372 | Part[lazyRange[4, 2], 2] 373 | , 374 | 6 375 | , 376 | TestID-> "9d97b9e9-95d1-4c32-be7b-1c7af9a10f48" 377 | ] 378 | 379 | VerificationTest[(* 44 *) 380 | First[Part[lazyRange[m], List[1, 2]]] 381 | , 382 | List[m, Plus[1, m]] 383 | , 384 | TestID->"208d84be-1c98-4209-a0f6-d832e7fc2b83" 385 | ] 386 | 387 | VerificationTest[(* 45 *) 388 | First[Part[lazyRange[m, n], Span[1, 3]]] 389 | , 390 | List[m, Plus[m, n], Plus[m, Times[2, n]]] 391 | , 392 | TestID->"e5808f50-f05b-429f-b532-45a4451a62f8" 393 | ] 394 | 395 | VerificationTest[(* 46 *) 396 | First[lazyRange[]] 397 | , 398 | 1 399 | , 400 | TestID->"b9198889-9149-4424-b10c-43d57703131e" 401 | ] 402 | 403 | VerificationTest[(* 47 *) 404 | Most[lazyRange[]] 405 | , 406 | List[1] 407 | , 408 | TestID->"dbf3e3e3-8e73-4b2f-a1d7-0f145d1e87e1" 409 | ] 410 | 411 | VerificationTest[(* 48 *) 412 | First[Last[lazyRange[]]] 413 | , 414 | 2 415 | , 416 | TestID->"d4851321-d20b-4240-83d1-aa2d81aa1e7c" 417 | ] 418 | 419 | VerificationTest[(* 49 *) 420 | Rest[lazyRange[]] 421 | , 422 | Last[lazyRange[]] 423 | , 424 | TestID->"49ad39c2-0849-4f5f-b430-9193a4949bc9" 425 | ] 426 | 427 | EndTestSection[] 428 | 429 | BeginTestSection["Part & Take"] 430 | 431 | VerificationTest[(* 50 *) 432 | Part[lazyRange[], 4] 433 | , 434 | 4 435 | , 436 | TestID->"ba87fc3c-eb8d-4448-8546-547454d4a9fb" 437 | ] 438 | 439 | VerificationTest[(* 51 *) 440 | CompoundExpression[Set[lz, Part[lazyRange[], List[4]]], First[lz]] 441 | , 442 | 4 443 | , 444 | TestID->"a4bc3d25-02c8-423d-92b4-9c5ac9fdff09" 445 | ] 446 | 447 | VerificationTest[(* 52 *) 448 | First[Last[lz]] 449 | , 450 | 5 451 | , 452 | TestID->"29f5d1ec-7934-4a76-81d2-ec1ec1be6c80" 453 | ] 454 | 455 | VerificationTest[(* 53 *) 456 | First[Rest[lz]] 457 | , 458 | 5 459 | , 460 | TestID->"8d821ca7-a9b9-4630-99f7-8a40c4cfaf6f" 461 | ] 462 | 463 | VerificationTest[(* 54 *) 464 | First[Part[lazyRange[], List[1, 4, 10, 5]]] 465 | , 466 | List[1, 4, 10, 5] 467 | , 468 | TestID->"6b6636be-5f74-4d4d-918b-e44168475c5f" 469 | ] 470 | 471 | VerificationTest[(* 55 *) 472 | First[Part[lazyRange[], Span[10, 2, -2]]] 473 | , 474 | List[10, 8, 6, 4, 2] 475 | , 476 | TestID->"26072312-18bb-48bd-8b29-c63cce600e6f" 477 | ] 478 | 479 | VerificationTest[(* 56 *) 480 | Map[First, lazyPartMap[lazyRange[], Range[2, 22, 4]]] 481 | , 482 | List[2, 6, 10, 14, 18, 22] 483 | , 484 | TestID->"95dae054-97de-45f6-ae80-bbbdcead8954" 485 | ] 486 | 487 | VerificationTest[(* 57 *) 488 | CompoundExpression[Set[lz, lazyList[Range[4]]], First[Part[lz, List[1, 2, 3, 4]]]] 489 | , 490 | List[1, 2, 3, 4] 491 | , 492 | TestID->"63bec182-5474-409f-81ca-9f28d83c0dfc" 493 | ] 494 | 495 | VerificationTest[(* 58 *) 496 | Part[lz, 5] 497 | , 498 | $Failed 499 | , 500 | {Part::partw} 501 | , 502 | TestID->"71b8cba2-0230-4342-90a4-9e869195a1c2" 503 | ] 504 | 505 | VerificationTest[(* 59 *) 506 | Part[lz, List[5]] 507 | , 508 | $Failed 509 | , 510 | {Part::partw} 511 | , 512 | TestID->"6a91f54c-35b3-4c44-86c6-96c0bde3c0df" 513 | ] 514 | 515 | VerificationTest[(* 60 *) 516 | Part[lz, List[2, 5]] 517 | , 518 | $Failed 519 | , 520 | {Part::partw} 521 | , 522 | TestID->"b2b4c750-b002-45f9-854c-da29568cb0c9" 523 | ] 524 | 525 | VerificationTest[(* 61 *) 526 | Part[lz, Span[2, 5]] 527 | , 528 | $Failed 529 | , 530 | {Part::partw} 531 | , 532 | TestID->"2bd7171f-20a3-4542-954e-8137f83dc785" 533 | ] 534 | 535 | VerificationTest[(* 62 *) 536 | CompoundExpression[Set[lz, Take[lazyRange[], 4]], First[lz]] 537 | , 538 | List[1, 2, 3, 4] 539 | , 540 | TestID->"5e0a950c-6c9b-479a-9577-f510d070b785" 541 | ] 542 | 543 | VerificationTest[(* 63 *) 544 | Most[lz] 545 | , 546 | List[List[1, 2, 3, 4]] 547 | , 548 | TestID->"fbd20cda-4809-49ed-91df-ad61c9b9c942" 549 | ] 550 | 551 | VerificationTest[(* 64 *) 552 | First[Rest[lz]] 553 | , 554 | 5 555 | , 556 | TestID->"11352ee2-0d75-44ae-b3cd-6f4a282119a2" 557 | ] 558 | 559 | VerificationTest[(* 65 *) 560 | First[Last[lz]] 561 | , 562 | 5 563 | , 564 | TestID->"27f2157e-5ce0-4e7b-9b23-c2c1c7ff64cb" 565 | ] 566 | 567 | VerificationTest[(* 66 *) 568 | First[Take[Last[lz], 5]] 569 | , 570 | List[5, 6, 7, 8, 9] 571 | , 572 | TestID->"fcd31aec-14e9-41b1-bd12-6ce307d8406f" 573 | ] 574 | 575 | VerificationTest[(* 67 *) 576 | First[Take[lazyRange[], List[5, 10]]] 577 | , 578 | List[5, 6, 7, 8, 9, 10] 579 | , 580 | TestID->"55c73f74-6a40-47f7-89eb-d36da337137c" 581 | ] 582 | 583 | VerificationTest[(* 68 *) 584 | CompoundExpression[Set[lz, Take[lazyRange[], List[10, 5]]], First[lz]] 585 | , 586 | List[10, 9, 8, 7, 6, 5] 587 | , 588 | TestID->"e961e37f-0278-4737-bff0-90e02ec06117" 589 | ] 590 | 591 | VerificationTest[(* 69 *) 592 | First[Last[lz]] 593 | , 594 | 11 595 | , 596 | TestID-> "576c82be-5968-4ce2-b54c-9a1c73b197e5" 597 | ] 598 | 599 | VerificationTest[(* 70 *) 600 | CompoundExpression[Set[lz, lazyList[Range[4]]], Take[lz, 5]] 601 | , 602 | lazyList[List[1, 2, 3, 4], lazyList[]] 603 | , 604 | TestID->"edf4f33b-9540-4ae5-b809-3e26f8ae02f8" 605 | ] 606 | 607 | VerificationTest[(* 71 *) 608 | Take[lz, List[3, 5]] 609 | , 610 | lazyList[List[3, 4], lazyList[]] 611 | , 612 | TestID->"871119d8-1679-42f3-b233-42e5a60e8432" 613 | ] 614 | 615 | VerificationTest[(* 72 *) 616 | Take[lz, List[5, 10]] 617 | , 618 | lazyList[] 619 | , 620 | TestID->"7125c3bc-998d-4824-92b5-8eadb7c0e4ff" 621 | ] 622 | 623 | VerificationTest[(* 73 *) 624 | Take[lz, List[10, 3]] 625 | , 626 | lazyList[List[4, 3], lazyList[]] 627 | , 628 | TestID->"dfcd0c72-873e-4da7-8046-867f8377fe08" 629 | ] 630 | 631 | VerificationTest[(* 74 *) 632 | lazyList[1, lazyRange[]] 633 | , 634 | lazyList[1, lazyRange[]] 635 | , 636 | TestID->"b015e0c0-8f15-4ee7-940e-c628d027f9eb" 637 | ] 638 | 639 | VerificationTest[(* 75 *) 640 | TakeDrop[lazyRange[], 5] 641 | , 642 | List[List[1, 2, 3, 4, 5], Blank[lazyList]] 643 | , 644 | TestID->"bbd9c60c-3e52-4d5c-b0da-fa8b1aed4844", SameTest->MatchQ 645 | ] 646 | 647 | VerificationTest[(* 76 *) 648 | AssociationMap[Function[TakeDrop[lazyList[Range[3]], Slot[1]]], Range[5]] 649 | , 650 | Association[Rule[1, List[List[1], lazyList[2, Blank[lazyList]]]], Rule[2, List[List[1, 2], lazyList[3, Blank[lazyList]]]], Rule[3, List[List[1, 2, 3], lazyList[]]], Rule[4, List[List[1, 2, 3], lazyList[]]], Rule[5, List[List[1, 2, 3], lazyList[]]]] 651 | , 652 | TestID->"07133d91-553e-44a5-980b-bac94a2a9acc", SameTest->MatchQ 653 | ] 654 | 655 | VerificationTest[(* 77 *) 656 | Drop[lazyRange[], 5] 657 | , 658 | Last[Take[lazyRange[], 5]] 659 | , 660 | TestID->"2cad0899-c41a-4b5c-a2ca-09822b847b3e" 661 | ] 662 | 663 | VerificationTest[(* 78 *) 664 | Map[Function[Drop[lazyList[Range[3]], Slot[1]]], Range[4]] 665 | , 666 | Map[Function[Last[Take[lazyList[Range[3]], Slot[1]]]], Range[4]] 667 | , 668 | TestID->"8979eca1-6251-4da4-aa30-ce937fa26f8d" 669 | ] 670 | 671 | EndTestSection[] 672 | 673 | BeginTestSection["TakeWhile & LengthWhile"] 674 | 675 | VerificationTest[(* 79 *) 676 | TakeWhile[lazyPowerRange[2, 2], Function[Less[Slot[1], 100]]] 677 | , 678 | lazyList[List[2, 4, 8, 16, 32, 64], lazyList[Blank[], Blank[]]] 679 | , 680 | TestID->"823b8a25-80e8-46f8-b67b-44cdddedf15b", SameTest-> MatchQ 681 | ] 682 | 683 | VerificationTest[(* 80 *) 684 | LengthWhile[lazyPowerRange[2, 2], Function[Less[Slot[1], 100]]] 685 | , 686 | Association[Rule["Index", 6], Rule["Element", lazyList[64, Blank[lazyList]]]] 687 | , 688 | TestID->"af7f0c1f-ca15-4c58-83bd-9d23e9dba98c", SameTest-> MatchQ 689 | ] 690 | 691 | EndTestSection[] 692 | 693 | BeginTestSection["Finite lists"] 694 | 695 | VerificationTest[(* 81 *) 696 | lazyList[Fibonacci[Range[10]]] 697 | , 698 | lazyList[1, lazyList[List[1, 2, 3, 5, 8, 13, 21, 34, 55]]] 699 | , 700 | TestID->"d8d804be-7edb-4c0f-9fc4-74513e0d407d" 701 | ] 702 | 703 | VerificationTest[(* 82 *) 704 | First[Take[lazyList[Fibonacci[Range[10]]], 5]] 705 | , 706 | List[1, 1, 2, 3, 5] 707 | , 708 | TestID->"6972598e-d646-4f13-8632-ea6074b82608" 709 | ] 710 | 711 | VerificationTest[(* 83 *) 712 | CompoundExpression[Set[fibList, Fibonacci[Range[10]]], Set[finiteLz, lazyList[Hold[fibList]]]] 713 | , 714 | lazyList[1, lazyLists`Private`lazyFiniteList[fibList, Plus[1, 1]]] 715 | , 716 | TestID->"dd7dc047-d5b9-4a27-bdd5-eea56763a8ee" 717 | ] 718 | 719 | VerificationTest[(* 84 *) 720 | First[Take[finiteLz, All]] 721 | , 722 | List[1, 1, 2, 3, 5, 8, 13, 21, 34, 55] 723 | , 724 | TestID->"6cabf47c-9bca-4941-93f1-b4db9a6519dd" 725 | ] 726 | 727 | VerificationTest[(* 85 *) 728 | CompoundExpression[Set[fibList, Fibonacci[Range[20]]], First[Take[finiteLz, All]]] 729 | , 730 | List[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765] 731 | , 732 | TestID->"4b556f22-babb-4365-9b20-0f83c95616ef" 733 | ] 734 | 735 | VerificationTest[(* 86 *) 736 | CompoundExpression[Set[fibList, Fibonacci[Range[1000]]], lazyFinitePart[finiteLz, 4]] 737 | , 738 | Part[fibList, 4] 739 | , 740 | TestID->"1f75b7a2-c9d4-4047-bbaa-274f038436fd" 741 | ] 742 | 743 | VerificationTest[(* 87 *) 744 | lazyFiniteTake[finiteLz, List[2, 4]] 745 | , 746 | Take[fibList, List[2, 4]] 747 | , 748 | TestID->"fcb2dcea-1434-4617-9121-24c0f4abf5ab" 749 | ] 750 | 751 | VerificationTest[(* 88 *) 752 | lazySetState[finiteLz, -1] 753 | , 754 | lazyList[43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875, lazyLists`Private`lazyFiniteList[fibList, Plus[1000, 1]]] 755 | , 756 | TestID->"4fd54ea8-9db6-4091-bebe-646a9fa05b5a" 757 | ] 758 | 759 | VerificationTest[(* 89 *) 760 | First[Take[lazyTranspose[List[lazyRange[], lazyConstantArray[0]]], 5]] 761 | , 762 | List[List[1, 0], List[2, 0], List[3, 0], List[4, 0], List[5, 0]] 763 | , 764 | TestID->"4b2cca41-177e-4c1e-a292-185fd30f3cd8" 765 | ] 766 | 767 | VerificationTest[(* 90 *) 768 | First[Take[lazyTranspose[List[lazyRange[], Range[5]]], All]] 769 | , 770 | List[List[1, 1], List[2, 2], List[3, 3], List[4, 4], List[5, 5]] 771 | , 772 | TestID->"7e29229f-4c36-47c4-b0cf-77b1e12970de" 773 | ] 774 | 775 | VerificationTest[(* 91 *) 776 | First[Take[lazyTruncate[lazyRange[], 10], 5]] 777 | , 778 | List[1, 2, 3, 4, 5] 779 | , 780 | TestID->"e0cea9ea-d5de-4f48-bd29-23d139e578c5" 781 | ] 782 | 783 | VerificationTest[(* 92 *) 784 | First[Take[Map[Log, lazyTruncate[lazyRange[], 10]], 5]] 785 | , 786 | List[0, Log[2], Log[3], Log[4], Log[5]] 787 | , 788 | TestID->"aeb778a2-d1ff-4dfe-a1b3-39ac250af7dc" 789 | ] 790 | 791 | VerificationTest[(* 93 *) 792 | First[Take[lazyTruncate[Map[Log, lazyRange[]], 10], 5]] 793 | , 794 | List[0, Log[2], Log[3], Log[4], Log[5]] 795 | , 796 | TestID->"c1ee8cf5-1678-4774-aab4-865c3590c396" 797 | ] 798 | 799 | VerificationTest[(* 94 *) 800 | First[Take[lazyTruncate[lazyRange[], 10], 20]] 801 | , 802 | List[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 803 | , 804 | TestID->"4b303bf3-71dd-47e9-8208-93dfd28bd79a" 805 | ] 806 | 807 | VerificationTest[(* 95 *) 808 | First[Take[Map[Log, lazyTruncate[lazyRange[], 10]], 20]] 809 | , 810 | List[0, Log[2], Log[3], Log[4], Log[5], Log[6], Log[7], Log[8], Log[9], Log[10]] 811 | , 812 | TestID->"bf209a66-bfc9-42b0-93f3-5819df531373" 813 | ] 814 | 815 | VerificationTest[(* 96 *) 816 | First[Take[lazyTruncate[Map[Log, lazyRange[]], 10], 20]] 817 | , 818 | List[0, Log[2], Log[3], Log[4], Log[5], Log[6], Log[7], Log[8], Log[9], Log[10]] 819 | , 820 | TestID->"1b31b9fa-d0a4-4a0f-9b0b-7ca9493dc612" 821 | ] 822 | 823 | EndTestSection[] 824 | 825 | EndTestSection[] 826 | 827 | BeginTestSection["partitionedLazyList"] 828 | 829 | BeginTestSection["Construction"] 830 | 831 | VerificationTest[(* 97 *) 832 | lazyPartition[lazyList[Fibonacci[Range[10]]], 5] 833 | , 834 | partitionedLazyList[List[1, 1, 2, 3, 5], lazyPartition[List[8, 13, 21, 34, 55], 5]] 835 | , 836 | TestID->"01bf8674-8020-456c-b246-5e53b2c6a0d1" 837 | ] 838 | 839 | VerificationTest[(* 98 *) 840 | Take[lazyPartition[lazyList[Fibonacci[Range[10]]], 5], All] 841 | , 842 | partitionedLazyList[List[1, 1, 2, 3, 5, 8, 13, 21, 34, 55], lazyList[]] 843 | , 844 | TestID->"c787722b-c06f-492e-ba9e-a6761bdb6ebc" 845 | ] 846 | 847 | VerificationTest[(* 99 *) 848 | Take[lazyPartition[Fibonacci[Range[10]], 5], All] 849 | , 850 | partitionedLazyList[List[1, 1, 2, 3, 5, 8, 13, 21, 34, 55], lazyList[]] 851 | , 852 | TestID->"732c1566-7183-4c6c-a41f-f2ac3016d1b6" 853 | ] 854 | 855 | VerificationTest[(* 100 *) 856 | Set[lz, partitionedLazyList[lazyGenerator[Range]]] 857 | , 858 | partitionedLazyList[List[1], partitionedLazyList[lazyLists`Private`twoSidedGenerator[Range, Plus[1, 1], 1]]] 859 | , 860 | TestID->"fe027550-a112-47ea-b5c6-c8fb3ab25ab3" 861 | ] 862 | 863 | VerificationTest[(* 101 *) 864 | Take[lz, 20] 865 | , 866 | partitionedLazyList[List[1, 1, 2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5], partitionedLazyList[List[6], partitionedLazyList[lazyLists`Private`twoSidedGenerator[Range, Plus[6, 1], 1]]]] 867 | , 868 | TestID->"74ee957c-35b9-4288-b87d-a44a6461a75a" 869 | ] 870 | 871 | VerificationTest[(* 102 *) 872 | First[Take[lz, 10]] 873 | , 874 | 1 875 | , 876 | TestID->"1530a19f-7b3b-4fa6-801e-235cb5df2ec0" 877 | ] 878 | 879 | VerificationTest[(* 103 *) 880 | Rest[Take[lz, 10]] 881 | , 882 | partitionedLazyList[List[1, 2, 1, 2, 3, 1, 2, 3, 4], partitionedLazyList[List[1, 2, 3, 4, 5], partitionedLazyList[lazyLists`Private`twoSidedGenerator[Range, Plus[5, 1], 1]]]] 883 | , 884 | TestID->"7414b466-3025-448c-8c06-5576951b0a84" 885 | ] 886 | 887 | VerificationTest[(* 104 *) 888 | Most[Take[lz, 10]] 889 | , 890 | List[1, 1, 2, 1, 2, 3, 1, 2, 3, 4] 891 | , 892 | TestID->"fa132159-8a8f-4beb-86df-e2bba144c4ef" 893 | ] 894 | 895 | VerificationTest[(* 105 *) 896 | Last[Take[lz, 10]] 897 | , 898 | partitionedLazyList[List[1, 2, 3, 4, 5], partitionedLazyList[lazyLists`Private`twoSidedGenerator[Range, Plus[5, 1], 1]]] 899 | , 900 | TestID->"5a9e1259-745c-4927-997b-aa932934f6e2" 901 | ] 902 | 903 | VerificationTest[(* 106 *) 904 | Set[lz, lazyPartition[lazyGenerator[Function[ConstantArray[Slot[1], 5]]], 3]] 905 | , 906 | partitionedLazyList[List[List[1, 1, 1, 1, 1], List[2, 2, 2, 2, 2], List[3, 3, 3, 3, 3]], lazyPartition[lazyLists`Private`twoSidedGenerator[Function[ConstantArray[Slot[1], 5]], Plus[3, 1], 1], 3]] 907 | , 908 | TestID->"5d38a3ac-f6bd-4521-8938-63627ebbfbdb" 909 | ] 910 | 911 | VerificationTest[(* 107 *) 912 | lazyTranspose[lz] 913 | , 914 | partitionedLazyList[List[List[1, 2, 3], List[1, 2, 3], List[1, 2, 3], List[1, 2, 3], List[1, 2, 3]], Map[List[Transpose, Listable], lazyPartition[lazyLists`Private`twoSidedGenerator[Function[ConstantArray[Slot[1], 5]], Plus[3, 1], 1], 3]]] 915 | , 916 | TestID->"29795b28-319d-4474-b894-5b87a8044998" 917 | ] 918 | 919 | EndTestSection[] 920 | 921 | BeginTestSection["Part and Take"] 922 | 923 | VerificationTest[(* 108 *) 924 | Set[lz, partitionedLazyRange[start, step, 5]] 925 | , 926 | partitionedLazyList[List[start, Plus[start, step], Plus[start, Times[2, step]], Plus[start, Times[3, step]], Plus[start, Times[4, step]]], partitionedLazyList[BlankSequence[]]] 927 | , 928 | TestID->"e48434ad-194e-4c1d-9181-bafefa2cd018", SameTest->MatchQ 929 | ] 930 | 931 | VerificationTest[(* 109 *) 932 | First[Take[lz, 20]] 933 | , 934 | start 935 | , 936 | TestID->"d1633934-c1bb-4947-a9ac-4f90c3f3a7da" 937 | ] 938 | 939 | VerificationTest[(* 110 *) 940 | Most[Take[lz, 20]] 941 | , 942 | List[start, Plus[start, step], Plus[start, Times[2, step]], Plus[start, Times[3, step]], Plus[start, Times[4, step]], Plus[start, Times[5, step]], Plus[start, Times[6, step]], Plus[start, Times[7, step]], Plus[start, Times[8, step]], Plus[start, Times[9, step]], Plus[start, Times[10, step]], Plus[start, Times[11, step]], Plus[start, Times[12, step]], Plus[start, Times[13, step]], Plus[start, Times[14, step]], Plus[start, Times[15, step]], Plus[start, Times[16, step]], Plus[start, Times[17, step]], Plus[start, Times[18, step]], Plus[start, Times[19, step]]] 943 | , 944 | TestID->"e3c13e65-15f5-40ab-a369-a0739f6ce9cd" 945 | ] 946 | 947 | VerificationTest[(* 111 *) 948 | Set[rangeRange, partitionedLazyList[lazyGenerator[Range, 1, 1, 8]]] 949 | , 950 | partitionedLazyList[List[1], partitionedLazyList[BlankSequence[]]] 951 | , 952 | TestID->"abbb180b-6296-4777-ac14-9878e48e5e91", SameTest->MatchQ 953 | ] 954 | 955 | VerificationTest[(* 112 *) 956 | Most[Take[rangeRange, 20]] 957 | , 958 | List[1, 1, 2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5] 959 | , 960 | TestID->"51609d85-e54a-44ed-91d9-4b64c4990fe4" 961 | ] 962 | 963 | VerificationTest[(* 113 *) 964 | Most[Take[rangeRange, List[18, 5, -3]]] 965 | , 966 | List[3, 5, 2, 3, 3] 967 | , 968 | TestID->"820df117-1d98-44c2-a62a-edec62a21a0a" 969 | ] 970 | 971 | VerificationTest[(* 114 *) 972 | Most[Take[rangeRange, List[5, 18, 3]]] 973 | , 974 | List[2, 2, 1, 4, 2] 975 | , 976 | TestID->"6dcf221b-d910-4a2e-b4e3-86711adeb89f" 977 | ] 978 | 979 | VerificationTest[(* 115 *) 980 | Most[lazyPartition[lazyRange[], 5]] 981 | , 982 | List[1, 2, 3, 4, 5] 983 | , 984 | TestID->"9a72acee-8279-49cc-b52e-428f405cc087" 985 | ] 986 | 987 | VerificationTest[(* 116 *) 988 | Most[lazyPartition[rangeRange, 5]] 989 | , 990 | List[1, 1, 2, 1, 2] 991 | , 992 | TestID->"e007465e-1e97-47b0-be7c-b8aac867396c" 993 | ] 994 | 995 | VerificationTest[(* 117 *) 996 | Most[lazyPartition[lazyPartition[lazyRange[], 5], 10]] 997 | , 998 | List[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 999 | , 1000 | TestID->"82525b95-d50e-41ef-b3f4-c8dc4e471c7e" 1001 | ] 1002 | 1003 | VerificationTest[(* 118 *) 1004 | Most[Take[lazyTruncate[partitionedLazyRange[10], 25], 5]] 1005 | , 1006 | List[1, 2, 3, 4, 5] 1007 | , 1008 | TestID->"f14281d3-eaf3-4020-a824-62abf93dba28" 1009 | ] 1010 | 1011 | VerificationTest[(* 119 *) 1012 | Most[Take[lazyTruncate[partitionedLazyRange[10], 25], 15]] 1013 | , 1014 | List[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] 1015 | , 1016 | TestID->"d3cf0a29-083f-45c8-b7cd-e0dd05f8f838" 1017 | ] 1018 | 1019 | VerificationTest[(* 120 *) 1020 | Most[Take[lazyTruncate[Map[Log, partitionedLazyRange[10]], 25], 15]] 1021 | , 1022 | List[0, Log[2], Log[3], Log[4], Log[5], Log[6], Log[7], Log[8], Log[9], Log[10], Log[11], Log[12], Log[13], Log[14], Log[15]] 1023 | , 1024 | TestID->"8426109a-6af3-4499-919c-dcd996f6167e" 1025 | ] 1026 | 1027 | VerificationTest[(* 121 *) 1028 | Most[Take[Map[Log, lazyTruncate[partitionedLazyRange[10], 25]], 15]] 1029 | , 1030 | List[0, Log[2], Log[3], Log[4], Log[5], Log[6], Log[7], Log[8], Log[9], Log[10], Log[11], Log[12], Log[13], Log[14], Log[15]] 1031 | , 1032 | TestID->"ac33716d-80d5-489b-899b-5c8a4e62fd8d" 1033 | ] 1034 | 1035 | VerificationTest[(* 122 *) 1036 | Most[Take[lazyTruncate[partitionedLazyRange[10], 25], 50]] 1037 | , 1038 | List[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25] 1039 | , 1040 | TestID->"8ebdf7c2-55e9-4b2f-8c3a-8feae18c691f" 1041 | ] 1042 | 1043 | VerificationTest[(* 123 *) 1044 | Most[Take[lazyTruncate[Map[Log, partitionedLazyRange[10]], 25], 50]] 1045 | , 1046 | List[0, Log[2], Log[3], Log[4], Log[5], Log[6], Log[7], Log[8], Log[9], Log[10], Log[11], Log[12], Log[13], Log[14], Log[15], Log[16], Log[17], Log[18], Log[19], Log[20], Log[21], Log[22], Log[23], Log[24], Log[25]] 1047 | , 1048 | TestID->"700bbfe1-4326-45e1-a89f-23332ffb1b64" 1049 | ] 1050 | 1051 | VerificationTest[(* 124 *) 1052 | Most[Take[Map[Log, lazyTruncate[partitionedLazyRange[10], 25]], 50]] 1053 | , 1054 | List[0, Log[2], Log[3], Log[4], Log[5], Log[6], Log[7], Log[8], Log[9], Log[10], Log[11], Log[12], Log[13], Log[14], Log[15], Log[16], Log[17], Log[18], Log[19], Log[20], Log[21], Log[22], Log[23], Log[24], Log[25]] 1055 | , 1056 | TestID->"62d9d377-d23d-433c-a4f8-4c088693c998" 1057 | ] 1058 | 1059 | VerificationTest[(* 125 *) 1060 | TakeDrop[partitionedLazyRange[10], 5] 1061 | , 1062 | List[List[1, 2, 3, 4, 5], Blank[partitionedLazyList]] 1063 | , 1064 | TestID->"bc6e4bf3-9ed7-494b-ac27-5e750f70b76f", SameTest->MatchQ 1065 | ] 1066 | 1067 | VerificationTest[(* 126 *) 1068 | TakeDrop[partitionedLazyRange[10], 15] 1069 | , 1070 | List[List[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], Blank[partitionedLazyList]] 1071 | , 1072 | TestID->"0a677117-8637-459e-a817-a24e88a77766", SameTest->MatchQ 1073 | ] 1074 | 1075 | VerificationTest[(* 127 *) 1076 | AssociationMap[Function[TakeDrop[partitionedLazyList[Range[3]], Slot[1]]], Range[5]] 1077 | , 1078 | Association[Rule[1, List[List[1], partitionedLazyList[List[2, 3], lazyList[]]]], Rule[2, List[List[1, 2], partitionedLazyList[List[3], lazyList[]]]], Rule[3, List[List[1, 2, 3], lazyList[]]], Rule[4, List[List[1, 2, 3], lazyList[]]], Rule[5, List[List[1, 2, 3], lazyList[]]]] 1079 | , 1080 | TestID->"9c71a79c-082e-453e-82ce-bf530ecbfb54" 1081 | ] 1082 | 1083 | VerificationTest[(* 128 *) 1084 | Map[Function[Drop[partitionedLazyRange[10], Slot[1]]], List[5, 15]] 1085 | , 1086 | Map[Function[Last[Take[partitionedLazyRange[10], Slot[1]]]], List[5, 15]] 1087 | , 1088 | TestID->"6c7a81da-7f2d-48f7-a8fd-02a660066d84" 1089 | ] 1090 | 1091 | VerificationTest[(* 129 *) 1092 | Map[Function[Drop[lazyPartition[Range[20], 10], Slot[1]]], List[5, 15, 25]] 1093 | , 1094 | Map[Function[Last[Take[lazyPartition[Range[20], 10], Slot[1]]]], List[5, 15, 25]] 1095 | , 1096 | TestID->"0ed52e26-9b2f-4d75-8088-8e628e3e6599" 1097 | ] 1098 | 1099 | EndTestSection[] 1100 | 1101 | BeginTestSection["lazyTuples"] 1102 | 1103 | VerificationTest[(* 130 *) 1104 | CompoundExpression[Set[lists, List[List[a, b, c], List[1, 2], List[u, v, w, x, y, z]]], Set[lzTup, lazyTuples[lists, Rule["PartitionSize", 10]]], MatchQ[lzTup, partitionedLazyList[List[List[a, 1, u], List[a, 1, v], List[a, 1, w], List[a, 1, x], List[a, 1, y], List[a, 1, z], List[a, 2, u], List[a, 2, v], List[a, 2, w], List[a, 2, x]], Blank[Map]]]] 1105 | , 1106 | True 1107 | , 1108 | TestID->"24b2d102-74b8-448e-b98e-e96436dc4582" 1109 | ] 1110 | 1111 | VerificationTest[(* 131 *) 1112 | Most[Take[lzTup, All]] 1113 | , 1114 | Tuples[lists] 1115 | , 1116 | TestID->"7e1cd504-6344-4ea6-945b-c5c473fce372" 1117 | ] 1118 | 1119 | VerificationTest[(* 132 *) 1120 | Most[Take[lazyTuples[List[a, b, c], 5], 10]] 1121 | , 1122 | Take[Tuples[List[a, b, c], 5], 10] 1123 | , 1124 | TestID->"2504436e-333c-4451-8e5c-5008d03ff2e1" 1125 | ] 1126 | 1127 | VerificationTest[(* 133 *) 1128 | CompoundExpression[Set[largeLists, Map[Range, List[50, 40, 60, 80]]], Most[Take[lazyTuples[Hold[largeLists]], 10]]] 1129 | , 1130 | List[List[1, 1, 1, 1], List[1, 1, 1, 2], List[1, 1, 1, 3], List[1, 1, 1, 4], List[1, 1, 1, 5], List[1, 1, 1, 6], List[1, 1, 1, 7], List[1, 1, 1, 8], List[1, 1, 1, 9], List[1, 1, 1, 10]] 1131 | , 1132 | TestID->"049881ce-6fad-454f-b4d5-405e0871d698" 1133 | ] 1134 | 1135 | VerificationTest[(* 134 *) 1136 | Most[Take[lazyTuples[Hold[largeLists], Rule["PartitionSize", 1000]], 100]] 1137 | , 1138 | List[List[1, 1, 1, 1], List[1, 1, 1, 2], List[1, 1, 1, 3], List[1, 1, 1, 4], List[1, 1, 1, 5], List[1, 1, 1, 6], List[1, 1, 1, 7], List[1, 1, 1, 8], List[1, 1, 1, 9], List[1, 1, 1, 10], List[1, 1, 1, 11], List[1, 1, 1, 12], List[1, 1, 1, 13], List[1, 1, 1, 14], List[1, 1, 1, 15], List[1, 1, 1, 16], List[1, 1, 1, 17], List[1, 1, 1, 18], List[1, 1, 1, 19], List[1, 1, 1, 20], List[1, 1, 1, 21], List[1, 1, 1, 22], List[1, 1, 1, 23], List[1, 1, 1, 24], List[1, 1, 1, 25], List[1, 1, 1, 26], List[1, 1, 1, 27], List[1, 1, 1, 28], List[1, 1, 1, 29], List[1, 1, 1, 30], List[1, 1, 1, 31], List[1, 1, 1, 32], List[1, 1, 1, 33], List[1, 1, 1, 34], List[1, 1, 1, 35], List[1, 1, 1, 36], List[1, 1, 1, 37], List[1, 1, 1, 38], List[1, 1, 1, 39], List[1, 1, 1, 40], List[1, 1, 1, 41], List[1, 1, 1, 42], List[1, 1, 1, 43], List[1, 1, 1, 44], List[1, 1, 1, 45], List[1, 1, 1, 46], List[1, 1, 1, 47], List[1, 1, 1, 48], List[1, 1, 1, 49], List[1, 1, 1, 50], List[1, 1, 1, 51], List[1, 1, 1, 52], List[1, 1, 1, 53], List[1, 1, 1, 54], List[1, 1, 1, 55], List[1, 1, 1, 56], List[1, 1, 1, 57], List[1, 1, 1, 58], List[1, 1, 1, 59], List[1, 1, 1, 60], List[1, 1, 1, 61], List[1, 1, 1, 62], List[1, 1, 1, 63], List[1, 1, 1, 64], List[1, 1, 1, 65], List[1, 1, 1, 66], List[1, 1, 1, 67], List[1, 1, 1, 68], List[1, 1, 1, 69], List[1, 1, 1, 70], List[1, 1, 1, 71], List[1, 1, 1, 72], List[1, 1, 1, 73], List[1, 1, 1, 74], List[1, 1, 1, 75], List[1, 1, 1, 76], List[1, 1, 1, 77], List[1, 1, 1, 78], List[1, 1, 1, 79], List[1, 1, 1, 80], List[1, 1, 2, 1], List[1, 1, 2, 2], List[1, 1, 2, 3], List[1, 1, 2, 4], List[1, 1, 2, 5], List[1, 1, 2, 6], List[1, 1, 2, 7], List[1, 1, 2, 8], List[1, 1, 2, 9], List[1, 1, 2, 10], List[1, 1, 2, 11], List[1, 1, 2, 12], List[1, 1, 2, 13], List[1, 1, 2, 14], List[1, 1, 2, 15], List[1, 1, 2, 16], List[1, 1, 2, 17], List[1, 1, 2, 18], List[1, 1, 2, 19], List[1, 1, 2, 20]] 1139 | , 1140 | TestID->"0a6ccfa4-19db-450c-91fe-c3131cfa38b5" 1141 | ] 1142 | 1143 | VerificationTest[(* 135 *) 1144 | CompoundExpression[Set[integers, Map[Length, lists]], Set[integerLzTup, lazyTuples[integers]], MatchQ[integerLzTup, partitionedLazyList[List[List[1, 1, 1], List[1, 1, 2], List[1, 1, 3], List[1, 1, 4], List[1, 1, 5], List[1, 1, 6], List[1, 2, 1], List[1, 2, 2], List[1, 2, 3], List[1, 2, 4]], Blank[Map]]]] 1145 | , 1146 | True 1147 | , 1148 | TestID->"abe8de04-193c-434c-9de1-f0e74ad365d8" 1149 | ] 1150 | 1151 | VerificationTest[(* 136 *) 1152 | Set[indices, Most[Take[integerLzTup, 10]]] 1153 | , 1154 | List[List[1, 1, 1], List[1, 1, 2], List[1, 1, 3], List[1, 1, 4], List[1, 1, 5], List[1, 1, 6], List[1, 2, 1], List[1, 2, 2], List[1, 2, 3], List[1, 2, 4]] 1155 | , 1156 | TestID->"1dc8febd-3448-49d6-be28-1ccd6ec9c3a9" 1157 | ] 1158 | 1159 | VerificationTest[(* 137 *) 1160 | Take[Tuples[Map[Range, integers]], 10] 1161 | , 1162 | List[List[1, 1, 1], List[1, 1, 2], List[1, 1, 3], List[1, 1, 4], List[1, 1, 5], List[1, 1, 6], List[1, 2, 1], List[1, 2, 2], List[1, 2, 3], List[1, 2, 4]] 1163 | , 1164 | TestID->"4d3ad108-8eda-4b86-b437-4ae9f711021e" 1165 | ] 1166 | 1167 | VerificationTest[(* 138 *) 1168 | bulkExtractElementsUsingIndexList[lists][Transpose[indices]] 1169 | , 1170 | Take[Tuples[lists], 10] 1171 | , 1172 | TestID->"aba8a778-a2ca-4ee0-b9cd-836bd89bf9f2" 1173 | ] 1174 | 1175 | VerificationTest[(* 139 *) 1176 | bulkExtractElementsUsingIndexList[Hold[lists]][Transpose[indices]] 1177 | , 1178 | Take[Tuples[lists], 10] 1179 | , 1180 | TestID->"cddc03cf-2e55-41ff-8f12-cfaf4b33ac36" 1181 | ] 1182 | 1183 | VerificationTest[(* 140 *) 1184 | Module[List[Set[list, List[a, b, c, d, e]], Set[tupLength, 3], indices], CompoundExpression[Set[indices, Most[Take[lazyTuples[Range[Length[list]], tupLength], 10]]], bulkExtractElementsUsingIndexList[list, tupLength][Transpose[indices]]]] 1185 | , 1186 | Take[Tuples[List[a, b, c, d, e], 3], 10] 1187 | , 1188 | TestID->"2cfc8d44-a522-49e1-a6d3-b57badf7858e" 1189 | ] 1190 | 1191 | VerificationTest[(* 141 *) 1192 | Most[Take[lazyTuples[integers, Rule["Start", 10]], 11]] 1193 | , 1194 | List[List[1, 2, 4], List[1, 2, 5], List[1, 2, 6], List[2, 1, 1], List[2, 1, 2], List[2, 1, 3], List[2, 1, 4], List[2, 1, 5], List[2, 1, 6], List[2, 2, 1], List[2, 2, 2]] 1195 | , 1196 | TestID->"6d6b52ee-9463-4ee8-be50-d35a81016de8" 1197 | ] 1198 | 1199 | VerificationTest[(* 142 *) 1200 | Take[Tuples[Map[Range, integers]], List[10, 20]] 1201 | , 1202 | List[List[1, 2, 4], List[1, 2, 5], List[1, 2, 6], List[2, 1, 1], List[2, 1, 2], List[2, 1, 3], List[2, 1, 4], List[2, 1, 5], List[2, 1, 6], List[2, 2, 1], List[2, 2, 2]] 1203 | , 1204 | TestID->"265a55bb-649d-416f-9440-2683e88bd339" 1205 | ] 1206 | 1207 | VerificationTest[(* 143 *) 1208 | CompoundExpression[Set[tuplesGenerator, rangeTuplesAtPositions[integers]], SameQ[Head[tuplesGenerator], CompiledFunction]] 1209 | , 1210 | True 1211 | , 1212 | TestID->"6039388a-a7fb-41f9-af49-0a1d7879ba7a" 1213 | ] 1214 | 1215 | VerificationTest[(* 144 *) 1216 | CompoundExpression[Set[randomPositions, RandomInteger[List[1, Apply[Times, integers]], 10]], MatchQ[randomPositions, List[BlankSequence[Integer]]]] 1217 | , 1218 | True 1219 | , 1220 | TestID->"89cad6c5-e497-4ab9-90a4-68a3e04af6ea" 1221 | ] 1222 | 1223 | VerificationTest[(* 145 *) 1224 | tuplesGenerator[randomPositions] 1225 | , 1226 | Transpose[Part[Tuples[Map[Range, integers]], randomPositions]] 1227 | , 1228 | TestID->"84552981-9693-4342-93a1-48f1974e46dc" 1229 | ] 1230 | 1231 | VerificationTest[(* 146 *) 1232 | CompoundExpression[Set[infTuples, lazyTuples[4]], MatchQ[infTuples, partitionedLazyList[List[List[1, 1, 1, 1], List[1, 1, 1, 2], List[1, 1, 2, 1], List[1, 2, 1, 1], List[2, 1, 1, 1], List[1, 1, 1, 3], List[1, 1, 2, 2], List[1, 1, 3, 1], List[1, 2, 1, 2], List[1, 2, 2, 1]], Blank[]]]] 1233 | , 1234 | True 1235 | , 1236 | TestID->"78889fbc-8259-4d38-97ef-1b93bd574df7" 1237 | ] 1238 | 1239 | VerificationTest[(* 147 *) 1240 | Most[Take[infTuples, 75]] 1241 | , 1242 | List[List[1, 1, 1, 1], List[1, 1, 1, 2], List[1, 1, 2, 1], List[1, 2, 1, 1], List[2, 1, 1, 1], List[1, 1, 1, 3], List[1, 1, 2, 2], List[1, 1, 3, 1], List[1, 2, 1, 2], List[1, 2, 2, 1], List[1, 3, 1, 1], List[2, 1, 1, 2], List[2, 1, 2, 1], List[2, 2, 1, 1], List[3, 1, 1, 1], List[1, 1, 1, 4], List[1, 1, 2, 3], List[1, 1, 3, 2], List[1, 1, 4, 1], List[1, 2, 1, 3], List[1, 2, 2, 2], List[1, 2, 3, 1], List[1, 3, 1, 2], List[1, 3, 2, 1], List[1, 4, 1, 1], List[2, 1, 1, 3], List[2, 1, 2, 2], List[2, 1, 3, 1], List[2, 2, 1, 2], List[2, 2, 2, 1], List[2, 3, 1, 1], List[3, 1, 1, 2], List[3, 1, 2, 1], List[3, 2, 1, 1], List[4, 1, 1, 1], List[1, 1, 1, 5], List[1, 1, 2, 4], List[1, 1, 3, 3], List[1, 1, 4, 2], List[1, 1, 5, 1], List[1, 2, 1, 4], List[1, 2, 2, 3], List[1, 2, 3, 2], List[1, 2, 4, 1], List[1, 3, 1, 3], List[1, 3, 2, 2], List[1, 3, 3, 1], List[1, 4, 1, 2], List[1, 4, 2, 1], List[1, 5, 1, 1], List[2, 1, 1, 4], List[2, 1, 2, 3], List[2, 1, 3, 2], List[2, 1, 4, 1], List[2, 2, 1, 3], List[2, 2, 2, 2], List[2, 2, 3, 1], List[2, 3, 1, 2], List[2, 3, 2, 1], List[2, 4, 1, 1], List[3, 1, 1, 3], List[3, 1, 2, 2], List[3, 1, 3, 1], List[3, 2, 1, 2], List[3, 2, 2, 1], List[3, 3, 1, 1], List[4, 1, 1, 2], List[4, 1, 2, 1], List[4, 2, 1, 1], List[5, 1, 1, 1], List[1, 1, 1, 6], List[1, 1, 2, 5], List[1, 1, 3, 4], List[1, 1, 4, 3], List[1, 1, 5, 2]] 1243 | , 1244 | TestID->"c70e9cab-91be-484e-883e-2f0f1f811260" 1245 | ] 1246 | 1247 | VerificationTest[(* 148 *) 1248 | Sort[Select[Most[Take[infTuples, 75]], Function[Less[Total[Slot[1]], 9]]]] 1249 | , 1250 | Sort[Select[Tuples[Range[10], 4], Function[Less[Total[Slot[1]], 9]]]] 1251 | , 1252 | TestID->"aa1b845f-e3c7-4baa-85ae-d14d3a58ac3e" 1253 | ] 1254 | 1255 | VerificationTest[(* 149 *) 1256 | Most[Take[lazyTuples[4, List[1, 4, 10, 2]], 20]] 1257 | , 1258 | List[List[1, 4, 10, 2], List[1, 4, 11, 1], List[1, 5, 1, 10], List[1, 5, 2, 9], List[1, 5, 3, 8], List[1, 5, 4, 7], List[1, 5, 5, 6], List[1, 5, 6, 5], List[1, 5, 7, 4], List[1, 5, 8, 3], List[1, 5, 9, 2], List[1, 5, 10, 1], List[1, 6, 1, 9], List[1, 6, 2, 8], List[1, 6, 3, 7], List[1, 6, 4, 6], List[1, 6, 5, 5], List[1, 6, 6, 4], List[1, 6, 7, 3], List[1, 6, 8, 2]] 1259 | , 1260 | TestID->"f3adf59a-4b10-4bd6-8798-52b9ea706312" 1261 | ] 1262 | 1263 | EndTestSection[] 1264 | 1265 | BeginTestSection["lazyStream"] 1266 | 1267 | VerificationTest[(* 150 *) 1268 | CompoundExpression[Set[stmp, OpenWrite["tmp"]], Write[stmp, a, b, c], Write[stmp, x], Write[stmp, "Hello"], Write[stmp, "Hello"], Write[stmp, "Hello"], Close[stmp]] 1269 | , 1270 | "tmp" 1271 | , 1272 | TestID->"0f990c29-bc3b-4212-b56f-dd4fc18990e6" 1273 | ] 1274 | 1275 | VerificationTest[(* 151 *) 1276 | Module[List[Set[stream, OpenRead["tmp"]], result], CompoundExpression[Set[result, First[Take[lazyStream[stream], 3]]], Close[stream], result]] 1277 | , 1278 | List[abc, x, "Hello"] 1279 | , 1280 | TestID->"52120357-4e6a-4818-9638-c55b4ec44945" 1281 | ] 1282 | 1283 | VerificationTest[(* 152 *) 1284 | Module[List[Set[stream, OpenRead["tmp"]], result], CompoundExpression[Set[result, First[TakeWhile[lazyStream[stream], Function[True]]]], Close[stream], DeleteFile["tmp"], result]] 1285 | , 1286 | List[abc, x, "Hello", "Hello", "Hello", EndOfFile] 1287 | , 1288 | TestID->"3a10c3aa-3bf6-467b-9474-a4f28c714065" 1289 | ] 1290 | 1291 | EndTestSection[] 1292 | 1293 | EndTestSection[] 1294 | 1295 | BeginTestSection["lazyListable"] 1296 | 1297 | VerificationTest[(* 153 *) 1298 | First[Take[Plus[lazyRange[], lazyRange[2]], 5]] 1299 | , 1300 | List[3, 5, 7, 9, 11] 1301 | , 1302 | TestID->"10ffdd73-035c-4ba5-a271-64a4e1bf04b9" 1303 | ] 1304 | 1305 | VerificationTest[(* 154 *) 1306 | First[Take[Plus[Times[2, lazyRange[]], Times[3, lazyRange[1, 2]]], 5]] 1307 | , 1308 | List[5, 13, 21, 29, 37] 1309 | , 1310 | TestID->"d7ff3a30-f6b5-4d8a-9ab2-ff7f8ed70d73" 1311 | ] 1312 | 1313 | VerificationTest[(* 155 *) 1314 | First[Take[Power[lazyRange[], lazyRange[]], 5]] 1315 | , 1316 | List[1, 4, 27, 256, 3125] 1317 | , 1318 | TestID->"cb32bc98-d965-431f-9f96-3ada1f100757" 1319 | ] 1320 | 1321 | VerificationTest[(* 156 *) 1322 | First[Take[Divide[1, lazyRange[2, 2]], 5]] 1323 | , 1324 | List[Times[1, Power[2, -1]], Times[1, Power[4, -1]], Times[1, Power[6, -1]], Times[1, Power[8, -1]], Times[1, Power[10, -1]]] 1325 | , 1326 | TestID->"88f9cdf0-0340-44dd-9935-af0cfe6259f5" 1327 | ] 1328 | 1329 | VerificationTest[(* 157 *) 1330 | setLazyListable[listableSymbol] 1331 | , 1332 | listableSymbol 1333 | , 1334 | TestID->"160be7e3-bf2c-448e-91f6-7bbd9a33e714" 1335 | ] 1336 | 1337 | VerificationTest[(* 158 *) 1338 | First[Take[listableSymbol[lazyRange[], lazyRange[2], 5], 5]] 1339 | , 1340 | List[listableSymbol[1, 2, 5], listableSymbol[2, 3, 5], listableSymbol[3, 4, 5], listableSymbol[4, 5, 5], listableSymbol[5, 6, 5]] 1341 | , 1342 | TestID->"c7310b38-f3a8-455d-920e-531b0051796e" 1343 | ] 1344 | 1345 | VerificationTest[(* 159 *) 1346 | CompoundExpression[SetAttributes[listableSymbol, List[Listable]], listableSymbol[lazyRange[], lazyRange[2], 5, List[1, 2]]] 1347 | , 1348 | List[lazyList[listableSymbol[1, 2, 5, 1], listableSymbol[BlankNullSequence[]]], lazyList[listableSymbol[1, 2, 5, 2], listableSymbol[BlankNullSequence[]]]] 1349 | , 1350 | TestID->"56038233-6e7c-403b-bd23-ff528dab83bf", SameTest->MatchQ 1351 | ] 1352 | 1353 | VerificationTest[(* 160 *) 1354 | First[Take[Plus[lazyRange[], lazyRange[]], 20]] 1355 | , 1356 | List[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40] 1357 | , 1358 | TestID->"b303f0b8-31df-472b-bf50-f5eef1970d6a" 1359 | ] 1360 | 1361 | VerificationTest[(* 161 *) 1362 | Most[Take[Plus[partitionedLazyRange[10], partitionedLazyRange[10]], 20]] 1363 | , 1364 | List[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40] 1365 | , 1366 | TestID-> "04ed330a-9048-4c6e-a7c6-b627ec4bb963" 1367 | ] 1368 | 1369 | VerificationTest[(* 162 *) 1370 | Most[Take[Plus[partitionedLazyRange[10], partitionedLazyRange[3]], 20]] 1371 | , 1372 | List[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40] 1373 | , 1374 | TestID->"97bb9fa9-efb3-4ee3-b236-66389f58bee3" 1375 | ] 1376 | 1377 | VerificationTest[(* 163 *) 1378 | Most[Take[Plus[partitionedLazyRange[10], lazyRange[]], 20]] 1379 | , 1380 | List[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40] 1381 | , 1382 | TestID->"0dab5eee-6788-4214-a369-18836d19f10a" 1383 | ] 1384 | 1385 | VerificationTest[(* 164 *) 1386 | Most[Take[Plus[Times[a, partitionedLazyList[lazyGenerator[Range, 1, 1]]], Times[b, Power[partitionedLazyList[lazyGenerator[Range, 2, 2]], -1]]], 5]] 1387 | , 1388 | List[Plus[a, b], Plus[a, Times[b, Power[2, -1]]], Plus[Times[2, a], b], Plus[a, Times[b, Power[2, -1]]], Plus[Times[2, a], Times[b, Power[3, -1]]]] 1389 | , 1390 | TestID->"c11cacfe-c700-4812-8a51-95a151ee3eaf" 1391 | ] 1392 | 1393 | VerificationTest[(* 165 *) 1394 | Most[Plus[partitionedLazyRange[3], partitionedLazyRange[5], partitionedLazyRange[6]]] 1395 | , 1396 | List[3, 6, 9, 12, 15, 18] 1397 | , 1398 | TestID->"b19f5a9c-bda9-4c9e-9d66-abbe90d7064d" 1399 | ] 1400 | 1401 | VerificationTest[(* 166 *) 1402 | setLazyListable[List[Sin, Listable]] 1403 | , 1404 | Sin 1405 | , 1406 | TestID->"33e34634-2c70-48c3-867d-7d1129c95903" 1407 | ] 1408 | 1409 | VerificationTest[(* 167 *) 1410 | Most[Sin[partitionedLazyRange[10]]] 1411 | , 1412 | List[Sin[1], Sin[2], Sin[3], Sin[4], Sin[5], Sin[6], Sin[7], Sin[8], Sin[9], Sin[10]] 1413 | , 1414 | TestID->"1cc79346-5d1d-4988-b0ce-81b7ae7f4be7" 1415 | ] 1416 | 1417 | EndTestSection[] 1418 | 1419 | BeginTestSection["Map"] 1420 | 1421 | VerificationTest[(* 168 *) 1422 | Reap[Most[Take[Map[Function[Sqrt[Sow[Slot[1]]]], partitionedLazyRange[3]], 4]]] 1423 | , 1424 | List[List[1, Sqrt[2], Sqrt[3], 2], List[List[1, 2, 3, 4, 5, 6]]] 1425 | , 1426 | TestID->"6440fb8d-a118-491f-88fd-43fd54af5daf" 1427 | ] 1428 | 1429 | VerificationTest[(* 169 *) 1430 | Reap[Most[Take[Map[List[Function[Sqrt[Sow[Slot[1]]]], Listable], partitionedLazyRange[3]], 4]]] 1431 | , 1432 | List[List[1, Sqrt[2], Sqrt[3], 2], List[List[List[1, 2, 3], List[4, 5, 6]]]] 1433 | , 1434 | TestID->"aff39ed4-8213-41e6-8228-aeceabbf621c" 1435 | ] 1436 | 1437 | VerificationTest[(* 170 *) 1438 | Map[Sqrt, lazyRange[0, 2]] 1439 | , 1440 | lazyList[0, Map[Sqrt, Blank[]]] 1441 | , 1442 | TestID->"c6d789ea-cab2-47f5-b533-b8d08cbea2f1", SameTest-> MatchQ 1443 | ] 1444 | 1445 | VerificationTest[(* 171 *) 1446 | First[Take[Map[Sqrt, lazyRange[0, 2]], 5]] 1447 | , 1448 | List[0, Sqrt[2], 2, Sqrt[6], Times[2, Sqrt[2]]] 1449 | , 1450 | TestID->"8e897f69-0991-43b0-a47e-33c4c2ad2605" 1451 | ] 1452 | 1453 | VerificationTest[(* 172 *) 1454 | Map[Cos, Map[Sin, Map[Exp, lazyRange[]]]] 1455 | , 1456 | lazyList[Cos[Sin[E]], Map[Cos, Map[Sin, Map[Exp, Blank[]]]]] 1457 | , 1458 | TestID->"fb24aab4-c206-439c-9a7b-3f300593d086", SameTest-> MatchQ 1459 | ] 1460 | 1461 | VerificationTest[(* 173 *) 1462 | composeMappedFunctions[Map[Cos, Map[Sin, Map[Exp, lazyRange[]]]]] 1463 | , 1464 | lazyList[Cos[Sin[E]], Map[Composition[Cos, Sin, Exp], Blank[]]] 1465 | , 1466 | TestID->"66f1eb1f-2b16-4e07-8261-69e9233b6d4f", SameTest-> MatchQ 1467 | ] 1468 | 1469 | VerificationTest[(* 174 *) 1470 | Map[Cos, Map[Exp, lazyGenerator[Sin]]] 1471 | , 1472 | lazyList[Cos[Power[E, Sin[1]]], Map[Cos, Map[Exp, lazyLists`Private`twoSidedGenerator[Sin, Plus[1, 1], 1]]]] 1473 | , 1474 | TestID->"f152549d-6a7c-4270-a618-b0ee9d3c21a9" 1475 | ] 1476 | 1477 | VerificationTest[(* 175 *) 1478 | composeMappedFunctions[Map[Cos, Map[Exp, lazyGenerator[Sin]]]] 1479 | , 1480 | lazyList[Cos[Power[E, Sin[1]]], lazyLists`Private`twoSidedGenerator[Composition[Cos, Exp, Sin], Plus[1, 1], 1]] 1481 | , 1482 | TestID->"cd24d0b2-3f35-4442-8db5-122d8b62a9fa" 1483 | ] 1484 | 1485 | VerificationTest[(* 176 *) 1486 | Most[Take[Map[f, Map[g, partitionedLazyRange[5]]], 10]] 1487 | , 1488 | List[f[g[1]], f[g[2]], f[g[3]], f[g[4]], f[g[5]], f[g[6]], f[g[7]], f[g[8]], f[g[9]], f[g[10]]] 1489 | , 1490 | TestID->"a5450e1b-fb2c-44eb-8b13-ade880632dd7" 1491 | ] 1492 | 1493 | VerificationTest[(* 177 *) 1494 | MatchQ[composeMappedFunctions[Map[f, Map[g, partitionedLazyRange[5]]]], partitionedLazyList[List[f[g[1]], f[g[2]], f[g[3]], f[g[4]], f[g[5]]], Map[Function[f[g[Slot[1]]]], Blank[]]]] 1495 | , 1496 | True 1497 | , 1498 | TestID->"476f6f8e-0110-4a8e-b2bd-81017fb9ea17" 1499 | ] 1500 | 1501 | VerificationTest[(* 178 *) 1502 | Most[Take[composeMappedFunctions[Map[f, Map[g, partitionedLazyRange[5]]]], 10]] 1503 | , 1504 | List[f[g[1]], f[g[2]], f[g[3]], f[g[4]], f[g[5]], f[g[6]], f[g[7]], f[g[8]], f[g[9]], f[g[10]]] 1505 | , 1506 | TestID->"97e07718-e310-4d36-8af1-187f48e2fc4b" 1507 | ] 1508 | 1509 | VerificationTest[(* 179 *) 1510 | Most[Take[Map[f, Map[List[Exp, Listable], partitionedLazyRange[5]]], 10]] 1511 | , 1512 | List[f[E], f[Power[E, 2]], f[Power[E, 3]], f[Power[E, 4]], f[Power[E, 5]], f[Power[E, 6]], f[Power[E, 7]], f[Power[E, 8]], f[Power[E, 9]], f[Power[E, 10]]] 1513 | , 1514 | TestID->"13563dea-b677-4304-9187-2d1566ecc789" 1515 | ] 1516 | 1517 | VerificationTest[(* 180 *) 1518 | MatchQ[composeMappedFunctions[Map[f, Map[List[Exp, Listable], partitionedLazyRange[5]]]], partitionedLazyList[List[f[E], f[Power[E, 2]], f[Power[E, 3]], f[Power[E, 4]], f[Power[E, 5]]], Map[List[Function[Map[f, Exp[Slot[1]]]], Listable], Blank[]]]] 1519 | , 1520 | True 1521 | , 1522 | TestID->"933709fd-737f-4c46-9d86-9b35f41696a2" 1523 | ] 1524 | 1525 | VerificationTest[(* 181 *) 1526 | Most[Take[Map[List[Exp, Listable], Map[f, partitionedLazyRange[5]]], 10]] 1527 | , 1528 | List[Power[E, f[1]], Power[E, f[2]], Power[E, f[3]], Power[E, f[4]], Power[E, f[5]], Power[E, f[6]], Power[E, f[7]], Power[E, f[8]], Power[E, f[9]], Power[E, f[10]]] 1529 | , 1530 | TestID->"8b28ed93-5599-4b12-b84d-bd37d052ecea" 1531 | ] 1532 | 1533 | VerificationTest[(* 182 *) 1534 | MatchQ[composeMappedFunctions[Map[List[Exp, Listable], Map[f, partitionedLazyRange[5]]]], partitionedLazyList[List[Power[E, f[1]], Power[E, f[2]], Power[E, f[3]], Power[E, f[4]], Power[E, f[5]]], Map[List[Function[Exp[Map[f, Slot[1]]]], Listable], Blank[]]]] 1535 | , 1536 | True 1537 | , 1538 | TestID->"6f341dd2-f2d3-41b5-a19e-e8565a0603be" 1539 | ] 1540 | 1541 | VerificationTest[(* 183 *) 1542 | Most[Take[Map[List[Cos, Listable], Map[List[Exp, Listable], partitionedLazyRange[5]]], 10]] 1543 | , 1544 | List[Cos[E], Cos[Power[E, 2]], Cos[Power[E, 3]], Cos[Power[E, 4]], Cos[Power[E, 5]], Cos[Power[E, 6]], Cos[Power[E, 7]], Cos[Power[E, 8]], Cos[Power[E, 9]], Cos[Power[E, 10]]] 1545 | , 1546 | TestID->"4e2acbd3-503b-4447-a034-2730b0328cb1" 1547 | ] 1548 | 1549 | VerificationTest[(* 184 *) 1550 | MatchQ[composeMappedFunctions[Map[List[Cos, Listable], Map[List[Exp, Listable], partitionedLazyRange[5]]]], partitionedLazyList[List[Cos[E], Cos[Power[E, 2]], Cos[Power[E, 3]], Cos[Power[E, 4]], Cos[Power[E, 5]]], Map[List[Function[Cos[Exp[Slot[1]]]], Listable], Blank[]]]] 1551 | , 1552 | True 1553 | , 1554 | TestID->"5d044afc-f4b7-4dfc-8614-388fa9ae2138" 1555 | ] 1556 | 1557 | VerificationTest[(* 185 *) 1558 | Take[Map[List[someFunction, Listable], partitionedLazyRange[3]], 4] 1559 | , 1560 | lazyList[] 1561 | , 1562 | {lazyList::take} 1563 | , 1564 | TestID->"e590682e-ebf3-47af-b876-76df923fbbb8" 1565 | ] 1566 | 1567 | VerificationTest[(* 186 *) 1568 | First[Take[MapIndexed[Function[List[Slot[1], Slot[2]]], lazyRange[2, 2]], 10]] 1569 | , 1570 | List[List[2, 1], List[4, 2], List[6, 3], List[8, 4], List[10, 5], List[12, 6], List[14, 7], List[16, 8], List[18, 9], List[20, 10]] 1571 | , 1572 | TestID->"c92d00e7-e6d1-47aa-a5f1-df872503201e" 1573 | ] 1574 | 1575 | VerificationTest[(* 187 *) 1576 | Most[Take[MapIndexed[Function[List[Slot[1], Slot[2]]], partitionedLazyRange[10, 2, 5]], 20]] 1577 | , 1578 | List[List[10, 1], List[12, 2], List[14, 3], List[16, 4], List[18, 5], List[20, 6], List[22, 7], List[24, 8], List[26, 9], List[28, 10], List[30, 11], List[32, 12], List[34, 13], List[36, 14], List[38, 15], List[40, 16], List[42, 17], List[44, 18], List[46, 19], List[48, 20]] 1579 | , 1580 | TestID->"940191b2-9c52-43c6-80e9-ca109bcf4440" 1581 | ] 1582 | 1583 | VerificationTest[(* 188 *) 1584 | First[Take[MapIndexed[Function[List[Slot[1], Slot[2]]], lazyRange[2, 2]], 5]] 1585 | , 1586 | List[List[2, 1], List[4, 2], List[6, 3], List[8, 4], List[10, 5]] 1587 | , 1588 | TestID->"755a2a31-5e94-41a8-b2bc-a72cb672099b" 1589 | ] 1590 | 1591 | VerificationTest[(* 189 *) 1592 | First[Take[MapIndexed[Function[List[Slot[1], Slot[2]]], lazyRange[], 20], 5]] 1593 | , 1594 | List[List[1, 20], List[2, 21], List[3, 22], List[4, 23], List[5, 24]] 1595 | , 1596 | TestID->"e7f47333-553c-4f61-bf2b-454329529868" 1597 | ] 1598 | 1599 | VerificationTest[(* 190 *) 1600 | First[Take[lazySetState[Map[f, lazyRange[]], 20], 5]] 1601 | , 1602 | List[f[20], f[21], f[22], f[23], f[24]] 1603 | , 1604 | TestID->"0d6c8aaf-3971-4513-b6b5-c7a976370960" 1605 | ] 1606 | 1607 | VerificationTest[(* 191 *) 1608 | CompoundExpression[Set[lst, Range[10]], lazySetState[Map[f, lazyList[Hold[lst]]], 5]] 1609 | , 1610 | lazyList[f[5], Map[f, lazyLists`Private`lazyFiniteList[lst, Plus[5, 1]]]] 1611 | , 1612 | TestID->"031e4dc8-5c16-47a2-9fc3-07410474c6bd" 1613 | ] 1614 | 1615 | VerificationTest[(* 192 *) 1616 | lazySetState[Map[f, lazyList[Hold[lst]]], 20] 1617 | , 1618 | lazyList[f[1], Map[f, lazyLists`Private`lazyFiniteList[lst, Plus[1, 1]]]] 1619 | , 1620 | {Part::partw} 1621 | , 1622 | TestID->"8bc09958-c00d-4608-a327-fb972e14312e" 1623 | ] 1624 | 1625 | EndTestSection[] 1626 | 1627 | BeginTestSection["Fold"] 1628 | 1629 | VerificationTest[(* 193 *) 1630 | FoldList[Plus, x0, lazyRange[n, m]] 1631 | , 1632 | lazyList[x0, FoldList[Plus, Plus[x0, n], Blank[]]] 1633 | , 1634 | TestID->"78ede253-0641-40d1-91a6-ada7c363db06", SameTest->MatchQ 1635 | ] 1636 | 1637 | VerificationTest[(* 194 *) 1638 | First[Take[FoldList[Plus, x0, lazyRange[n, m]], 5]] 1639 | , 1640 | List[x0, Plus[n, x0], Plus[m, Times[2, n], x0], Plus[Times[3, m], Times[3, n], x0], Plus[Times[6, m], Times[4, n], x0]] 1641 | , 1642 | TestID->"db188c97-bab5-4d20-9c9c-d317201c07d3" 1643 | ] 1644 | 1645 | VerificationTest[(* 195 *) 1646 | First[Take[FoldList[Function[If[Less[Slot[2], 15], Nothing, Slot[2]]], Nothing, lazyRange[10]], 20]] 1647 | , 1648 | List[15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34] 1649 | , 1650 | TestID->"4f3d6397-e664-44d8-a0cf-3e752dc62c3c" 1651 | ] 1652 | 1653 | VerificationTest[(* 196 *) 1654 | Most[Take[FoldList[Function[If[Less[Slot[2], 15], Nothing, Slot[2]]], Nothing, partitionedLazyRange[10]], 20]] 1655 | , 1656 | List[15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34] 1657 | , 1658 | TestID->"40919827-ae18-4769-8793-82574d5ca24b" 1659 | ] 1660 | 1661 | VerificationTest[(* 197 *) 1662 | First[Take[FoldPairList[Function[List[p[Slot[1], Slot[2]], q[Slot[1], Slot[2]]]], u, lazyRange[]], 6]] 1663 | , 1664 | List[p[u, 1], p[q[u, 1], 2], p[q[q[u, 1], 2], 3], p[q[q[q[u, 1], 2], 3], 4], p[q[q[q[q[u, 1], 2], 3], 4], 5], p[q[q[q[q[q[u, 1], 2], 3], 4], 5], 6]] 1665 | , 1666 | TestID->"22e0751b-1a8b-4c64-ab0d-7d245c004db7" 1667 | ] 1668 | 1669 | VerificationTest[(* 198 *) 1670 | Most[Take[FoldPairList[Function[List[p[Slot[1], Slot[2]], q[Slot[1], Slot[2]]]], u, partitionedLazyRange[3]], 6]] 1671 | , 1672 | List[p[u, 1], p[q[u, 1], 2], p[q[q[u, 1], 2], 3], p[q[q[q[u, 1], 2], 3], 4], p[q[q[q[q[u, 1], 2], 3], 4], 5], p[q[q[q[q[q[u, 1], 2], 3], 4], 5], 6]] 1673 | , 1674 | TestID->"3991fc43-240c-4484-b447-79575b7081c3" 1675 | ] 1676 | 1677 | VerificationTest[(* 199 *) 1678 | FoldPairList[TakeDrop, lazyRange[], List[2, 3, 6, 10]] 1679 | , 1680 | List[List[1, 2], List[3, 4, 5], List[6, 7, 8, 9, 10, 11], List[12, 13, 14, 15, 16, 17, 18, 19, 20, 21]] 1681 | , 1682 | TestID->"a66185cd-0733-4052-863c-2a7522eea654" 1683 | ] 1684 | 1685 | VerificationTest[(* 200 *) 1686 | FoldPairList[TakeDrop, partitionedLazyRange[10], List[2, 3, 6, 10]] 1687 | , 1688 | List[List[1, 2], List[3, 4, 5], List[6, 7, 8, 9, 10, 11], List[12, 13, 14, 15, 16, 17, 18, 19, 20, 21]] 1689 | , 1690 | TestID->"ccd1e34b-4c67-499f-9528-b5716c21f95d" 1691 | ] 1692 | 1693 | VerificationTest[(* 201 *) 1694 | Most[Take[FoldPairList[TakeDrop, lazyRange[], lazyRange[]], 10]] 1695 | , 1696 | List[List[List[1], List[2, 3], List[4, 5, 6], List[7, 8, 9, 10], List[11, 12, 13, 14, 15], List[16, 17, 18, 19, 20, 21], List[22, 23, 24, 25, 26, 27, 28], List[29, 30, 31, 32, 33, 34, 35, 36], List[37, 38, 39, 40, 41, 42, 43, 44, 45], List[46, 47, 48, 49, 50, 51, 52, 53, 54, 55]]] 1697 | , 1698 | TestID->"4dc80dfa-8008-44cc-aac8-6cf0c9fb94bf" 1699 | ] 1700 | 1701 | VerificationTest[(* 202 *) 1702 | Most[Take[FoldPairList[TakeDrop, partitionedLazyRange[10], partitionedLazyRange[10]], 10]] 1703 | , 1704 | List[List[1], List[2, 3], List[4, 5, 6], List[7, 8, 9, 10], List[11, 12, 13, 14, 15], List[16, 17, 18, 19, 20, 21], List[22, 23, 24, 25, 26, 27, 28], List[29, 30, 31, 32, 33, 34, 35, 36], List[37, 38, 39, 40, 41, 42, 43, 44, 45], List[46, 47, 48, 49, 50, 51, 52, 53, 54, 55]] 1705 | , 1706 | TestID->"e65bea94-a585-402f-9550-59754f63bad2" 1707 | ] 1708 | 1709 | EndTestSection[] 1710 | 1711 | BeginTestSection["Cases, Pick, Select"] 1712 | 1713 | VerificationTest[(* 203 *) 1714 | MatchQ[Cases[lazyRange[0, Times[2, Power[3, -1]]], Blank[Integer]], lazyList[0, Blank[]]] 1715 | , 1716 | True 1717 | , 1718 | TestID->"eef58711-9a2b-4adf-bb35-fd6ddc3b49a1" 1719 | ] 1720 | 1721 | VerificationTest[(* 204 *) 1722 | First[Take[Cases[lazyRange[0, Times[2, Power[3, -1]]], Blank[Integer]], 5]] 1723 | , 1724 | List[0, 2, 4, 6, 8] 1725 | , 1726 | TestID->"1c11a617-94ea-42b9-bf57-ccb346d33046" 1727 | ] 1728 | 1729 | VerificationTest[(* 205 *) 1730 | MatchQ[Pick[lazyRange[0, 2], lazyRange[0, Times[2, Power[3, -1]]], Blank[Integer]], lazyList[0, Blank[]]] 1731 | , 1732 | True 1733 | , 1734 | TestID->"df1ac686-6c55-4310-b8be-df2063f48b70" 1735 | ] 1736 | 1737 | VerificationTest[(* 206 *) 1738 | First[Take[Pick[lazyRange[0, 2], lazyRange[0, Times[2, Power[3, -1]]], Blank[Integer]], 5]] 1739 | , 1740 | List[0, 6, 12, 18, 24] 1741 | , 1742 | TestID->"232b3f69-ae25-4cc2-9e08-7fc39008ebff" 1743 | ] 1744 | 1745 | VerificationTest[(* 207 *) 1746 | Select[lazyRange[], OddQ] 1747 | , 1748 | lazyList[1, Select[Blank[], OddQ]] 1749 | , 1750 | TestID->"8d8036f1-5720-4811-8629-7c25ce67842b", SameTest->MatchQ 1751 | ] 1752 | 1753 | VerificationTest[(* 208 *) 1754 | First[Take[Select[lazyRange[], OddQ], 5]] 1755 | , 1756 | List[1, 3, 5, 7, 9] 1757 | , 1758 | TestID->"2ff4ea71-a191-4c9f-9760-83fb52d4606d" 1759 | ] 1760 | 1761 | EndTestSection[] 1762 | 1763 | BeginTestSection["lazyMapThread, lazyTranspose"] 1764 | 1765 | VerificationTest[(* 209 *) 1766 | First[Take[lazyMapThread[f, List[lazyRange[], lazyRange[2, 2]]], 5]] 1767 | , 1768 | List[f[1, 2], f[2, 4], f[3, 6], f[4, 8], f[5, 10]] 1769 | , 1770 | TestID->"713e38e1-53ae-455a-bbf8-0bbc02d45524" 1771 | ] 1772 | 1773 | VerificationTest[(* 210 *) 1774 | MapThread[f, List[Range[5], Times[2, Range[5]]]] 1775 | , 1776 | List[f[1, 2], f[2, 4], f[3, 6], f[4, 8], f[5, 10]] 1777 | , 1778 | TestID->"04ba0346-ff2e-4659-8597-53624df2a10d" 1779 | ] 1780 | 1781 | VerificationTest[(* 211 *) 1782 | First[Take[lazyMapThread[f, List[lazyRange[], Range[5]]], All]] 1783 | , 1784 | List[f[1, 1], f[2, 2], f[3, 3], f[4, 4], f[5, 5]] 1785 | , 1786 | TestID->"32188d20-9d34-4122-bf92-06bb3cf26702" 1787 | ] 1788 | 1789 | VerificationTest[(* 212 *) 1790 | Most[Take[lazyMapThread[f, List[partitionedLazyList[Map[Range, lazyRange[]]], partitionedLazyRange[4], partitionedLazyRange[2, 2, 6]]], 10]] 1791 | , 1792 | List[f[1, 1, 2], f[1, 2, 4], f[2, 3, 6], f[1, 4, 8], f[2, 5, 10], f[3, 6, 12], f[1, 7, 14], f[2, 8, 16], f[3, 9, 18], f[4, 10, 20]] 1793 | , 1794 | TestID->"1da06e68-9eab-497a-92fa-298cc059d2a2" 1795 | ] 1796 | 1797 | VerificationTest[(* 213 *) 1798 | lazyMapThread[f, List[partitionedLazyRange[3], lazyRange[]]] 1799 | , 1800 | partitionedLazyList[List[f[1, 1], f[2, 2], f[3, 3]], lazyMapThread[f, Blank[]]] 1801 | , 1802 | TestID->"afa9dc39-c825-4926-a453-fdf3dc86c42d", SameTest->MatchQ 1803 | ] 1804 | 1805 | VerificationTest[(* 214 *) 1806 | First[Take[lazyTranspose[List[lazyRange[], lazyRange[start]]], 5]] 1807 | , 1808 | List[List[1, start], List[2, Plus[1, start]], List[3, Plus[2, start]], List[4, Plus[3, start]], List[5, Plus[4, start]]] 1809 | , 1810 | TestID->"6f32f0a8-9388-4926-998a-161b2cdd31a4" 1811 | ] 1812 | 1813 | VerificationTest[(* 215 *) 1814 | First[Take[lazyMapThread[List, List[lazyRange[], lazyRange[start]]], 5]] 1815 | , 1816 | List[List[1, start], List[2, Plus[1, start]], List[3, Plus[2, start]], List[4, Plus[3, start]], List[5, Plus[4, start]]] 1817 | , 1818 | TestID->"6d546c3e-83bb-4b12-832a-cc468addc674" 1819 | ] 1820 | 1821 | EndTestSection[] 1822 | 1823 | BeginTestSection["lazyCatenate"] 1824 | 1825 | VerificationTest[(* 216 *) 1826 | lazyCatenate[List[List[1, 2]]] 1827 | , 1828 | lazyList[1, lazyList[List[2]]] 1829 | , 1830 | TestID->"d44e1a68-eed8-4007-8121-b5732cbc3f46" 1831 | ] 1832 | 1833 | VerificationTest[(* 217 *) 1834 | lazyCatenate[List[lazyRange[]]] 1835 | , 1836 | lazyRange[] 1837 | , 1838 | TestID->"5a71142c-3026-4188-bf98-8c2241e3e39e" 1839 | ] 1840 | 1841 | VerificationTest[(* 218 *) 1842 | lazyCatenate[List[partitionedLazyRange[5]]] 1843 | , 1844 | partitionedLazyRange[5] 1845 | , 1846 | TestID->"503585d1-e1e3-4211-9795-8c4c977a7c4d" 1847 | ] 1848 | 1849 | VerificationTest[(* 219 *) 1850 | lazyCatenate[List[List[1, 2], List[2, 3, 4]]] 1851 | , 1852 | lazyList[1, lazyList[List[2, 2, 3, 4]]] 1853 | , 1854 | TestID->"b2868662-c220-4ca5-9934-cf1408f55c4c" 1855 | ] 1856 | 1857 | VerificationTest[(* 220 *) 1858 | First[Take[lazyCatenate[List[List[1, 2], List[2, 3, 4]]], All]] 1859 | , 1860 | List[1, 2, 2, 3, 4] 1861 | , 1862 | TestID->"26cc958a-8c1c-46fb-8da0-897ff4d162d5" 1863 | ] 1864 | 1865 | VerificationTest[(* 221 *) 1866 | First[Take[lazyCatenate[List[lazyGenerator[f, 1, 1, 5], lazyGenerator[g, 1, 1, 5]]], All]] 1867 | , 1868 | List[f[1], f[2], f[3], f[4], f[5], g[1], g[2], g[3], g[4], g[5]] 1869 | , 1870 | TestID->"23dbb7e0-0165-415b-873b-c8ea5d62ef15" 1871 | ] 1872 | 1873 | VerificationTest[(* 222 *) 1874 | First[Take[lazyCatenate[lazyGenerator[Range, 1, 1, 5]], All]] 1875 | , 1876 | List[1, 1, 2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 5] 1877 | , 1878 | TestID->"6b951aba-15c0-4b1d-942a-9a5eb2395281" 1879 | ] 1880 | 1881 | VerificationTest[(* 223 *) 1882 | First[Take[lazyCatenate[lazyGenerator[Function[lazyGenerator[Subscript[f, Slot[1]], Slot[1], Slot[1], Plus[Slot[1], 3]]], 1, 1, 5]], All]] 1883 | , 1884 | List[Subscript[f, 1][1], Subscript[f, 1][2], Subscript[f, 1][3], Subscript[f, 1][4], Subscript[f, 2][2], Subscript[f, 2][3], Subscript[f, 2][4], Subscript[f, 2][5], Subscript[f, 3][3], Subscript[f, 3][4], Subscript[f, 3][5], Subscript[f, 3][6], Subscript[f, 4][4], Subscript[f, 4][5], Subscript[f, 4][6], Subscript[f, 4][7], Subscript[f, 5][5], Subscript[f, 5][6], Subscript[f, 5][7], Subscript[f, 5][8]] 1885 | , 1886 | TestID->"5a550561-3bb0-4958-ae50-af45c4caf47c" 1887 | ] 1888 | 1889 | EndTestSection[] 1890 | 1891 | BeginTestSection["endOfLazyList"] 1892 | 1893 | VerificationTest[(* 224 *) 1894 | lazyList[endOfLazyList, "stuff"] 1895 | , 1896 | lazyList[] 1897 | , 1898 | TestID->"9dc7e6eb-3363-4834-a585-2c2a9296a68d" 1899 | ] 1900 | 1901 | VerificationTest[(* 225 *) 1902 | lazyList[endOfLazyList, lazyRange[]] 1903 | , 1904 | lazyList[] 1905 | , 1906 | TestID->"4f792f28-e364-415a-b4ef-4bcfc98a7be5" 1907 | ] 1908 | 1909 | VerificationTest[(* 226 *) 1910 | partitionedLazyList[List[1, 2, 3, endOfLazyList, otherStuff], anyTail] 1911 | , 1912 | partitionedLazyList[List[1, 2, 3], lazyList[]] 1913 | , 1914 | TestID->"94817bc0-0d2d-4936-a5db-71739d8c11d6" 1915 | ] 1916 | 1917 | VerificationTest[(* 227 *) 1918 | Take[Map[f, partitionedLazyList[List[1, 2, 3], partitionedLazyList[List[4, 5, 6, endOfLazyList, Apply[Sequence, Range[10]]], partitionedLazyRange[5]]]], 20] 1919 | , 1920 | partitionedLazyList[List[f[1], f[2], f[3], f[4], f[5], f[6]], lazyList[]] 1921 | , 1922 | TestID->"ed006187-1cdf-429c-bf81-1372cb1c21b2" 1923 | ] 1924 | 1925 | VerificationTest[(* 228 *) 1926 | Take[Map[g, Map[f, partitionedLazyList[List[1, 2, 3], partitionedLazyList[List[4, 5, 6, endOfLazyList, Apply[Sequence, Range[10]]], partitionedLazyRange[5]]]]], 20] 1927 | , 1928 | partitionedLazyList[List[g[f[1]], g[f[2]], g[f[3]], g[f[4]], g[f[5]], g[f[6]]], lazyList[]] 1929 | , 1930 | TestID->"570c9489-e01d-4aa5-aa36-9409385fa8bf" 1931 | ] 1932 | 1933 | VerificationTest[(* 229 *) 1934 | Take[Map[g, Map[List[Sin, Listable], partitionedLazyList[List[1, 2, 3], partitionedLazyList[List[4, 5, 6, endOfLazyList, Apply[Sequence, Range[10]]], partitionedLazyRange[5]]]]], 20] 1935 | , 1936 | partitionedLazyList[List[g[Sin[1]], g[Sin[2]], g[Sin[3]], g[Sin[4]], g[Sin[5]], g[Sin[6]]], lazyList[]] 1937 | , 1938 | TestID->"a82e8b8e-e760-4b09-8799-a58114510cc3" 1939 | ] 1940 | 1941 | VerificationTest[(* 230 *) 1942 | Take[Map[List[Sqrt, Listable], Map[List[Sin, Listable], partitionedLazyList[List[1, 2, 3], partitionedLazyList[List[4, 5, 6, endOfLazyList, Apply[Sequence, Range[10]]], partitionedLazyRange[5]]]]], 20] 1943 | , 1944 | partitionedLazyList[List[Sqrt[Sin[1]], Sqrt[Sin[2]], Sqrt[Sin[3]], Sqrt[Sin[4]], Sqrt[Sin[5]], Sqrt[Sin[6]]], lazyList[]] 1945 | , 1946 | TestID->"7f54badb-04eb-4387-839f-c61a96a88f32" 1947 | ] 1948 | 1949 | VerificationTest[(* 231 *) 1950 | Take[Map[List[Sqrt, Listable], Map[f, partitionedLazyList[List[1, 2, 3], partitionedLazyList[List[4, 5, 6, endOfLazyList, Apply[Sequence, Range[10]]], partitionedLazyRange[5]]]]], 20] 1951 | , 1952 | partitionedLazyList[List[Sqrt[f[1]], Sqrt[f[2]], Sqrt[f[3]], Sqrt[f[4]], Sqrt[f[5]], Sqrt[f[6]]], lazyList[]] 1953 | , 1954 | TestID->"081a33cc-6d46-4a5d-9e20-4f80c8af8f5c" 1955 | ] 1956 | 1957 | VerificationTest[(* 232 *) 1958 | Take[Map[Sin, Map[Function[If[Greater[Slot[1], 10], endOfLazyList, Slot[1]]], lazyRange[]]], 20] 1959 | , 1960 | lazyList[List[Sin[1], Sin[2], Sin[3], Sin[4], Sin[5], Sin[6], Sin[7], Sin[8], Sin[9], Sin[10]], lazyList[]] 1961 | , 1962 | TestID->"d45fb48f-f591-4dc9-8f64-ddaa030a3ebd" 1963 | ] 1964 | 1965 | VerificationTest[(* 233 *) 1966 | Take[Map[Sin, Map[Function[If[Greater[Slot[1], 10], endOfLazyList, Slot[1]]], partitionedLazyRange[5]]], 20] 1967 | , 1968 | partitionedLazyList[List[Sin[1], Sin[2], Sin[3], Sin[4], Sin[5], Sin[6], Sin[7], Sin[8], Sin[9], Sin[10]], lazyList[]] 1969 | , 1970 | TestID->"cb8edc20-4697-48dd-bd1b-bf5a62532ba3" 1971 | ] 1972 | 1973 | VerificationTest[(* 234 *) 1974 | Take[Map[List[Sin, Listable], Map[Function[If[Greater[Slot[1], 10], endOfLazyList, Slot[1]]], partitionedLazyRange[5]]], 20] 1975 | , 1976 | partitionedLazyList[List[Sin[1], Sin[2], Sin[3], Sin[4], Sin[5], Sin[6], Sin[7], Sin[8], Sin[9], Sin[10]], lazyList[]] 1977 | , 1978 | TestID->"33c42b6a-5684-46b6-b03b-de033e81ecc1" 1979 | ] 1980 | 1981 | VerificationTest[(* 235 *) 1982 | Take[Map[Sin, Map[List[Function[If[Greater[Max[Slot[1]], 10], Append[Slot[1], endOfLazyList], Slot[1]]], Listable], partitionedLazyRange[5]]], 20] 1983 | , 1984 | partitionedLazyList[List[Sin[1], Sin[2], Sin[3], Sin[4], Sin[5], Sin[6], Sin[7], Sin[8], Sin[9], Sin[10], Sin[11], Sin[12], Sin[13], Sin[14], Sin[15]], lazyList[]] 1985 | , 1986 | TestID->"827b77e3-adc4-411d-9a3d-cfd9afce8fd8" 1987 | ] 1988 | 1989 | VerificationTest[(* 236 *) 1990 | Take[Map[List[Sin, Listable], Map[List[Function[If[Greater[Max[Slot[1]], 10], Append[Slot[1], endOfLazyList], Slot[1]]], Listable], partitionedLazyRange[5]]], 20] 1991 | , 1992 | partitionedLazyList[List[Sin[1], Sin[2], Sin[3], Sin[4], Sin[5], Sin[6], Sin[7], Sin[8], Sin[9], Sin[10], Sin[11], Sin[12], Sin[13], Sin[14], Sin[15]], lazyList[]] 1993 | , 1994 | TestID->"73355d47-e7bc-43ca-af53-c934312e1588" 1995 | ] 1996 | 1997 | VerificationTest[(* 237 *) 1998 | Take[composeMappedFunctions[Map[Sin, Map[Function[If[SameQ[Slot[1], 10], endOfLazyList, Slot[1]]], lazyRange[]]]], 20] 1999 | , 2000 | Take[Map[Sin, Map[Function[If[SameQ[Slot[1], 10], endOfLazyList, Slot[1]]], lazyRange[]]], 20] 2001 | , 2002 | TestID->"d8075c3e-aa4f-4c8f-b42e-6b89ece12e84" 2003 | ] 2004 | 2005 | EndTestSection[] 2006 | 2007 | BeginTestSection["lazyAggregate"] 2008 | 2009 | VerificationTest[(* 238 *) 2010 | CompoundExpression[Set[nmax, Power[10, 4]], lazyAggregate[lazyTruncate[partitionedLazyRange[100], nmax], List[CountsBy[PrimeQ], Merge[Total]]]] 2011 | , 2012 | List[Association[Rule[False, 8771], Rule[True, 1229]], lazyList[]] 2013 | , 2014 | TestID->"00720e91-d9ae-4630-894d-b79a77912522" 2015 | ] 2016 | 2017 | VerificationTest[(* 239 *) 2018 | CompoundExpression[Set[List[result, tail], lazyAggregate[partitionedLazyRange[100], List[CountsBy[PrimeQ], Merge[Total]], Power[10, 4]]], result] 2019 | , 2020 | Association[Rule[False, 8771], Rule[True, 1229]] 2021 | , 2022 | TestID->"9d1ed9dc-6f28-4bb0-ac33-faffadfbd46e" 2023 | ] 2024 | 2025 | VerificationTest[(* 240 *) 2026 | First[lazyAggregate[tail, List[CountsBy[PrimeQ], Merge[Total]], Power[10, 4]]] 2027 | , 2028 | Association[Rule[False, 8967], Rule[True, 1033]] 2029 | , 2030 | TestID->"a2850e34-4c80-430d-ae46-9d038dfd767e" 2031 | ] 2032 | 2033 | VerificationTest[(* 241 *) 2034 | First[lazyAggregate[lazyRange[], List[CountsBy[PrimeQ], Merge[Total]], Power[10, 4], 100]] 2035 | , 2036 | Association[Rule[False, 8771], Rule[True, 1229]] 2037 | , 2038 | TestID->"b1cc1458-5bb0-42ea-b8cd-795dd4b8fd7b" 2039 | ] 2040 | 2041 | VerificationTest[(* 242 *) 2042 | lazyAggregate[lazyTruncate[lazyRange[], Power[10, 4]], List[CountsBy[PrimeQ], Merge[Total]], Infinity, 10] 2043 | , 2044 | List[Association[Rule[False, 8771], Rule[True, 1229]], lazyList[]] 2045 | , 2046 | TestID->"32157966-3dcb-4245-8ce7-887ab4af0bc1" 2047 | ] 2048 | 2049 | EndTestSection[] 2050 | 2051 | BeginTestSection["AnyTrue etc."] 2052 | 2053 | VerificationTest[(* 243 *) 2054 | AssociationMap[Function[Slot[1][lazyList[], f]], List[AnyTrue, AllTrue, NoneTrue]] 2055 | , 2056 | Association[Rule[AnyTrue, False], Rule[AllTrue, True], Rule[NoneTrue, True]] 2057 | , 2058 | TestID->"57928a8b-9706-473e-b3cd-37b085633c9c" 2059 | ] 2060 | 2061 | VerificationTest[(* 244 *) 2062 | AssociationMap[Function[Slot[1][lazyRange[], Function[Less[Slot[1], 100]]]], List[AnyTrue, AllTrue, NoneTrue]] 2063 | , 2064 | Association[Rule[AnyTrue, True], Rule[AllTrue, False], Rule[NoneTrue, False]] 2065 | , 2066 | TestID->"6177e1d4-4861-439e-9804-67f36a0d299c" 2067 | ] 2068 | 2069 | VerificationTest[(* 245 *) 2070 | AssociationMap[Function[Slot[1][lazyTruncate[lazyRange[], 99], Function[Greater[Slot[1], 100]]]], List[AnyTrue, AllTrue, NoneTrue]] 2071 | , 2072 | Association[Rule[AnyTrue, False], Rule[AllTrue, False], Rule[NoneTrue, True]] 2073 | , 2074 | TestID->"841b2ab8-4f34-4641-8949-fc5e1e56186a" 2075 | ] 2076 | 2077 | VerificationTest[(* 246 *) 2078 | AssociationMap[Function[Slot[1][lazyTruncate[lazyRange[], 99], Function[Less[Slot[1], 100]]]], List[AnyTrue, AllTrue, NoneTrue]] 2079 | , 2080 | Association[Rule[AnyTrue, True], Rule[AllTrue, True], Rule[NoneTrue, False]] 2081 | , 2082 | TestID->"b5c9b699-3441-464e-9c50-cf1ec32ca193" 2083 | ] 2084 | 2085 | EndTestSection[] 2086 | 2087 | BeginTestSection["Edge cases"] 2088 | 2089 | VerificationTest[(* 247 *) 2090 | Set[badExample, Function[lazyList[1, Slot[0][]]][]] 2091 | , 2092 | lazyList[1, Function[lazyList[1, Slot[0][]]][]] 2093 | , 2094 | TestID->"cca6f375-6ddb-4152-aa3d-2349457bc8e2" 2095 | ] 2096 | 2097 | VerificationTest[(* 248 *) 2098 | Last[badExample] 2099 | , 2100 | badExample 2101 | , 2102 | TestID->"d5669f68-30d9-4e7a-a0e0-4a892a683a43" 2103 | ] 2104 | 2105 | VerificationTest[(* 249 *) 2106 | First[Take[badExample, 20]] 2107 | , 2108 | List[1, 1] 2109 | , 2110 | TestID->"0820b214-6494-4848-9ae0-3811250773bb" 2111 | ] 2112 | 2113 | VerificationTest[(* 250 *) 2114 | Set[example, Function[lazyList[1, Slot[0][Plus[Slot[1], 1]]]][1]] 2115 | , 2116 | lazyList[1, Function[lazyList[1, Slot[0][Plus[Slot[1], 1]]]][Plus[1, 1]]] 2117 | , 2118 | TestID->"70bea84b-fb82-4ee1-8fff-c75fed296f60" 2119 | ] 2120 | 2121 | VerificationTest[(* 251 *) 2122 | SameQ[example, Last[example]] 2123 | , 2124 | False 2125 | , 2126 | TestID->"1346241a-d07f-43e4-b438-f6bb7f8bcc01" 2127 | ] 2128 | 2129 | VerificationTest[(* 252 *) 2130 | Take[example, 20] 2131 | , 2132 | lazyList[List[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], Function[lazyList[1, Slot[0][Plus[Slot[1], 1]]]][Plus[20, 1]]] 2133 | , 2134 | TestID->"8cc85caf-0ded-497b-bc70-c8c40b5ed440" 2135 | ] 2136 | 2137 | VerificationTest[(* 253 *) 2138 | Set[position, Replace[Last[Take[example, 20]], List[RuleDelayed[lazyList[Blank[], Function[BlankSequence[]][Pattern[i, Blank[]]]], i]]]] 2139 | , 2140 | 22 2141 | , 2142 | TestID->"276824c8-0ef1-470e-ab70-bcf516bda143" 2143 | ] 2144 | 2145 | EndTestSection[] 2146 | 2147 | EndTestSection[] 2148 | -------------------------------------------------------------------------------- /lazyLists-1.0.paclet: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssmit1986/lazyLists/b4abc5bf20dbf8be59e71e20838f0dd7e2549bcb/lazyLists-1.0.paclet -------------------------------------------------------------------------------- /lazyLists/Kernel/DefaultsAndMessages.wl: -------------------------------------------------------------------------------- 1 | (* Wolfram Language Package *) 2 | 3 | (* Created by the Wolfram Workbench 18-Sep-2018 *) 4 | BeginPackage["lazyLists`"] 5 | (* Exported symbols added here with SymbolName::usage *) 6 | 7 | Begin["`Private`"] 8 | (* Implementation of the package *) 9 | 10 | twoSidedGenerator[___] := lazyList[]; 11 | leftSidedGenerator[___] := lazyList[]; 12 | rightSidedGenerator[___] := lazyList[]; 13 | finiteGenerator[___] := lazyList[]; 14 | 15 | 16 | lazySetState::notSupported = "lazySetState is not supported for lazyList `1`"; 17 | lazySetState[l_lazyList, _] := (Message[lazySetState::notSupported, Short[l]]; l) 18 | 19 | 20 | lazyList::notFinite = "lazyList `1` cannot be recognised as a finite list"; 21 | lazyFinitePart[lz : lzPattern, _] := (Message[lazyList::notFinite, Short[lz]]; $Failed); 22 | lazyFiniteTake[lz : lzPattern, _] := (Message[lazyList::notFinite, Short[lz]]; $Failed); 23 | 24 | 25 | lazyCatenate::invrp = "Argument `1` is not a valid list or lazyList"; 26 | lazyCatenate[{___, arg : Except[_List | lzPattern | heldListPattern], ___}] := (Message[lazyCatenate::invrp, Short[arg]]; $Failed); 27 | lazyCatenate[lazyList[arg : Except[_List | _lazyList], _]] := (Message[lazyCatenate::invrp, Short[arg]]; $Failed); 28 | 29 | lazyTruncate::int = "Argument `1` should be a positive integer"; 30 | lazyTruncate[arg : Except[lzPattern], _] := (Message[lazyTruncate::invrp, Short[arg]]; $Failed); 31 | lazyTruncate[_, i : Except[_Integer?Positive]] := (Message[lazyTruncate::int, Short[i]]; $Failed); 32 | 33 | (* Default failure messages for Take and Part *) 34 | 35 | Scan[ 36 | Function[{ 37 | head 38 | }, 39 | head::illDefined = "lazyList `1` is not well-defined"; 40 | Scan[ 41 | Function[ 42 | head /: Alternatives[Part, Take, TakeWhile, LengthWhile][lz : #, ___] := 43 | (Message[head::illDefined, Short[lz]]; $Failed) 44 | ], 45 | {head[_], head[_, _, __]} 46 | ] 47 | ], 48 | {lazyList, partitionedLazyList} 49 | ]; 50 | 51 | 52 | lazyList::take = "Cannot take `1` in `2`"; 53 | lazyList /: Take[lz_lazyList, spec_, ___] := (Message[lazyList::take, spec, Short[lz]]; lazyList[]); 54 | lazyList::part = "Cannot take part `1` in `2`"; 55 | lazyList /: Part[lz_lazyList, spec_, ___] := (Message[lazyList::part, spec, Short[lz]]; $Failed); 56 | 57 | partitionedLazyList::take = "Cannot take `1` in `2`"; 58 | partitionedLazyList /: Take[lz_partitionedLazyList, spec_, ___] := (Message[lazyList::take, spec, Short[lz]]; lazyList[]); 59 | partitionedLazyList::part = "Cannot take part `1` in `2`"; 60 | partitionedLazyList /: Part[lz_partitionedLazyList, spec_, ___] := (Message[lazyList::part, spec, Short[lz]]; $Failed); 61 | 62 | lazyMapThread[___] := lazyList[]; 63 | 64 | End[] 65 | 66 | EndPackage[] 67 | 68 | -------------------------------------------------------------------------------- /lazyLists/Kernel/UsageMessages.wl: -------------------------------------------------------------------------------- 1 | (* Wolfram Language Package *) 2 | 3 | (* Created by the Wolfram Workbench 18-Sep-2018 *) 4 | BeginPackage["lazyLists`"] 5 | (* Exported symbols added here with SymbolName::usage *) 6 | 7 | lazyList::usage = "lazyList is a linked-list data structure that should contain 2 elements: the first is the first element, the second a held expression that will generate the next linked list when evaluated. 8 | You can extract these elements explicitely with First and Last/Rest. Part and Take have been overloaded with special functionalities when used on lazyList and will iteratively evaluate the tail to collect elements from the lazyList. 9 | lazyList[list] or lazyList[Hold[var]] is a special constructor that generates a lazyList from an ordinary list."; 10 | 11 | lazyRange::usage = "lazyRange[] is a lazy representation of the Integers from 1 to \[Infinity]. lazyRange[min, delta] represents values values from min onwards in steps of delta. 12 | lazyRange has no upper limit and is generally slightly faster than lazyGenerator."; 13 | 14 | lazyPowerRange::usage = "lazyPowerRange[min, r] is the infinite list {min, r \[Times] min, r^2 \[Times] min, ...}"; 15 | 16 | lazyNestList::usage = "lazyNestList[f, elem] is the infinite list {elem, f[elem], f[f[elem]], ...} starting with elem and generated by iterating f repeatedly."; 17 | 18 | lazyFixedPointList::usage = "lazyFixedPointList[f, elem, sameTest] nests f to elem until the result not longer changes according to sameTest."; 19 | 20 | lazyStream::usage = "lazyStream[streamObject] creates a lazyList that streams from streamObject. These streams will stop automatically when EndOfFile is reached."; 21 | 22 | lazyConstantArray::usage = "lazyConstantArray[elem] produces an infinite list of copies of elem."; 23 | 24 | lazyMapThread::usage = "lazyMapThread[f, {lz1, lz2, ...}] is the lazy equivalent to MapThread. Mixing lazy lists and normal lists is allowed."; 25 | 26 | lazyTranspose::usage = "lazyTranspose[{lz1, lz2, ...}] creates a lazyList with tuples of elements from lz1, lz2, etc. 27 | Equivalent to lazyMapThread[Identity, {lz1, lz2, ...}]"; 28 | 29 | lazyPartMap::usage = "lazyPartMap[l, {i, j, k, ...}] is equivalent to Map[Part[l, {#}]&, {i, j, k, ...}] but faster."; 30 | 31 | lazyFinitePart::usage = "lazyFinitePart[lz, i, j, k,...] directly extracts Part from finite and periodic lazyLists without having to traverse the lazyList element-by-element. 32 | It is equivalent to Part[list, i, j, k, ...]"; 33 | 34 | lazyFiniteTake::usage = "lazyFiniteTake[lz, spec] directly applies Take to finite lazyLists and periodic lazyLists without having to traverse the lazyList element-by-element. 35 | It is equivalent to Take[list, spec]"; 36 | 37 | lazySetState::usage = "lazySetState[lz, state] with lz a supported lazyList returns a lazyList at the specified state. 38 | Finite lists, lazyPeriodicList, lists generated with lazyGenerator, lazy(Power)Range, and lazyNestList are supported. 39 | Maps over supported lists are also supported."; 40 | 41 | lazyGenerator::usage = "lazyGenerator[f, start, min, max, step] generates a lazyList that applies f to values {start, start + step, start + 2 step, ...} for values between min and max (which are allowed to be infinite). 42 | When min and max are both infinite, symbolic values for start and step are allowed."; 43 | 44 | lazyPeriodicList::usage = "lazyPeriodicList[list] is an infinite lazyList that cycles through the values in list periodically."; 45 | 46 | $lazyIterationLimit::usage = "Iteration limit used for finding successive elements in a lazy list."; 47 | 48 | emptyLazyListQ::usage = "emptyLazyListQ tests if an expression is equal to lazyList[]"; 49 | endOfLazyList::usage = "A special token that will terminate any lazyList whenever it is encountered."; 50 | 51 | partitionedLazyList::usage = "Is a special wrapper for lazyLists that generate ordinary Lists. 52 | The elements of the inner Lists are treated as if they're seperate elements of the outer lazyList, making it possible to generate elements in chunks. 53 | List operations on partitionedLazyList such as Map and FoldList will be automatically applied to the generated lists for efficiency."; 54 | 55 | partitionedLazyRange::usage = "partitionedLazyRange[start, step, partitionLength] works like lazyRange, but yields a partitionedLazyList. 56 | partitionedLazyRange[partitionLength] generates the natural numbers in chuncks of length partitionLength."; 57 | 58 | partitionedLazyNestList::usage = "partitionedLazyNestList[fun, elem, partitionLength] is a partitioned version of lazyNestList. 59 | Each new partition is generated with NestList."; 60 | 61 | lazyPartition::usage = "lazyPartition[l, n] turns an ordinary list or lazyList into a partitioned lazyList with chunks of length n."; 62 | 63 | 64 | lazyCatenate::usage = "lazyCatenate catenates lists of lazyLists, lazyLists of lists and lazyLists of lazyLists into one lazyList."; 65 | 66 | setLazyListable::usage = "setLazyListable[sym] sets UpValues to lazyList that ensure that sym threads over lazyLists. 67 | Be aware that the attributes have priority over UpValues, so if sym has the Listable attribute it will always act first."; 68 | 69 | lazyPrependTo::usage = "lazyPrependTo[lz, element] can be used on lazyLists generated by lazyList[Hold[var]] or lazyList[list] to modify the underlying list. 70 | It returns a lazyList with the modified variable at the index where lz was originally."; 71 | 72 | lazyAppendTo::usage = "lazyAppendTo[lz, element] can be used on lazyLists generated by lazyList[Hold[var]] or lazyList[list] to modify the underlying list. 73 | It returns a lazyList with the modified variable at the index where lz was originally."; 74 | 75 | lazyTuples::usage = "lazyTuples is a lazy version of Tuples with mostly the same syntax. 76 | lazyTuples[n] is a special case that generates an infinite list of all n-tuples of integers \[GreaterEqual] 1."; 77 | nextIntegerTuple::usage = "nextIntegerTuple[{int1, int2, ...}] generates the next integer tuple in a canonical order."; 78 | 79 | bulkExtractElementsUsingIndexList::usage = "bulkExtractElementsUsingIndexList[lists, indices] converts elements from Tuples[Range /@ Length /@ lists] into elements from Tuples[lists]"; 80 | 81 | rangeTuplesAtPositions::usage = "rangeTuplesAtPositions[Length /@ lists] is a CompiledFunction that directly generates elements of Tuples[Range /@ Length /@ lists]"; 82 | 83 | repartitionAll::usage = "repartitionAll[{lz1, lz2, ...}] returns the list of lazy lists, but with all partitioned lazylists restructured to be of the same partition length. Ordinary lazyLists will be converted to partitionedLazyLists."; 84 | 85 | composeMappedFunctions::usage = "composeMappedFunctions[lzList] will convert mappings of the form f /@ g /@ ... /@ lzList to a single map of the form (f @* g @* ...) /@ lzList "; 86 | 87 | lazyTruncate::usage = "lazyTruncate[lzList, int] truncates a (possibly infinite) lazyList to finite length."; 88 | 89 | lazyAggregate::usage = "lazyAggregate[lzList, {aggregator, combiner}, batchSize, maxItems] iteratively extracts batchSize elements from lzList and then aggregates the values with the aggregator. The combiner aggregates results from multiple batches."; 90 | 91 | EndPackage[] 92 | 93 | -------------------------------------------------------------------------------- /lazyLists/Kernel/lazyConstructors.wl: -------------------------------------------------------------------------------- 1 | (* Wolfram Language Package *) 2 | 3 | (* Created by the Wolfram Workbench 18-Sep-2018 *) 4 | 5 | BeginPackage["lazyLists`"] 6 | (* Exported symbols added here with SymbolName::usage *) 7 | 8 | 9 | Begin["`Private`"] 10 | (* Implementation of the package *) 11 | 12 | lzPattern = _lazyList | _partitionedLazyList; 13 | lzHead = lazyList | partitionedLazyList; 14 | emptyLazyListQ = Function[# === lazyList[]]; 15 | validLazyListPattern = lazyList[_, _]; 16 | validPartitionedLazyListPattern = partitionedLazyList[_List, _]; 17 | nonEmptyLzListPattern = validLazyListPattern | validPartitionedLazyListPattern 18 | heldListPattern = Hold[_Symbol?ListQ]; 19 | 20 | $lazyIterationLimit = Infinity; 21 | 22 | Attributes[lazyList] = {HoldRest}; 23 | 24 | lazyList[{}] := lazyList[]; 25 | lazyList[Nothing, tail_] := tail; 26 | lazyList[{fst_, rest___}] := lazyList[fst, lazyList[{rest}]]; 27 | lazyList[endOfLazyList, ___] := lazyList[] 28 | 29 | 30 | Attributes[lazyFiniteList] = {HoldFirst}; 31 | lazyList::noList = "Symbol `1` is not a list"; 32 | 33 | lazyList[Hold[list_Symbol?ListQ]] := lazyFiniteList[list, 1]; 34 | lazyList[Hold[list_Symbol]] := ( 35 | Message[lazyList::noList, HoldForm[list]]; 36 | lazyList[] 37 | ); 38 | 39 | With[{ 40 | msgs = {Part::partw} 41 | }, 42 | (* Don't test patterns for performance. It's up to the user to make sure nothing illegal ends up in lazyFiniteList if they decide to use it *) 43 | lazyFiniteList[list_, i_] := Quiet[ 44 | Check[ 45 | lazyList[list[[i]], lazyFiniteList[list, i + 1]], 46 | lazyList[], 47 | msgs 48 | ], 49 | msgs 50 | ] 51 | ]; 52 | 53 | lazyFinitePart[lzHead[_, HoldPattern[(lazyFiniteList | lazyPeriodicListInternal)[list_, __]]], spec__] := Part[list, spec]; 54 | lazyFiniteTake[lzHead[_, HoldPattern[(lazyFiniteList | lazyPeriodicListInternal)[list_, __]]], spec_] := Take[list, spec]; 55 | 56 | lazySetState[lzHead[_, HoldPattern @ lazyFiniteList[list_, _, rest___]], index_Integer] /; 0 < index <= Length[list] := 57 | lazyFiniteList[list, index, rest]; 58 | 59 | lazySetState[lzHead[_, HoldPattern @ lazyFiniteList[list_, _, rest___]], index_Integer] /; -Length[list] <= index < 0 := 60 | lazyFiniteList[list, index + Length[list] + 1, rest]; 61 | 62 | lazySetState[lz : lzHead[_, HoldPattern @ lazyFiniteList[list_, _, ___]], index_Integer] := ( 63 | Message[Part::partw, index, Short[lz]]; 64 | lz 65 | ); 66 | 67 | lazyGenerator::badSpec = "Cannot create lazyGenerator with specifications `1`. Empty lazyList was returned"; 68 | lazyGenerator[ 69 | f_, 70 | start : _ : 1, 71 | min : _ : DirectedInfinity[-1], max : _ : DirectedInfinity[1], step : _ : 1 72 | ] := Replace[ 73 | Switch[ {min, max, start, step}, 74 | {DirectedInfinity[-1], DirectedInfinity[1], __}, 75 | twoSidedGenerator[f, start, step], 76 | {DirectedInfinity[-1], _?NumericQ, _?NumericQ, _?NumericQ}, 77 | leftSidedGenerator[f, start, max, step], 78 | {_?NumericQ, DirectedInfinity[1], _?NumericQ, _?NumericQ}, 79 | rightSidedGenerator[f, start, min, step], 80 | {_?NumericQ, _?NumericQ,_?NumericQ, _?NumericQ}, 81 | finiteGenerator[f, start, min, max, step], 82 | _, 83 | lazyList[] 84 | ], 85 | { 86 | lazyList[] :> ( 87 | Message[ 88 | lazyGenerator::badSpec, 89 | AssociationThread[{"min", "max", "start", "step"}, {min, max, start, step}] 90 | ]; 91 | lazyList[] 92 | ) 93 | } 94 | ]; 95 | 96 | twoSidedGenerator[f_, pos_, step_] := lazyList[ 97 | f[pos], 98 | twoSidedGenerator[f, pos + step, step] 99 | ]; 100 | 101 | leftSidedGenerator[f_, pos_, max_, step_] /; pos <= max := lazyList[ 102 | f[pos], 103 | leftSidedGenerator[f, pos + step, max, step] 104 | ]; 105 | 106 | rightSidedGenerator[f_, pos_, min_, step_] /; min <= pos := lazyList[ 107 | f[pos], 108 | rightSidedGenerator[f, pos + step, min, step] 109 | ]; 110 | 111 | finiteGenerator[f_, pos_, min_, max_, step_] /; Between[pos, {min, max}] := lazyList[ 112 | f[pos], 113 | finiteGenerator[f, pos + step, min, max, step] 114 | ]; 115 | 116 | generatorPattern = Alternatives[twoSidedGenerator, leftSidedGenerator, rightSidedGenerator, finiteGenerator]; 117 | 118 | With[{ (* pattern needs to be With'ed in because of the HoldRest attribute of lazyList *) 119 | patt = generatorPattern 120 | }, 121 | lazySetState[ 122 | l : lazyList[ 123 | _, 124 | (gen : patt)[f_, pos_, rest___] 125 | ], 126 | state_ 127 | ] := Replace[ 128 | Check[gen[f, state, rest], $Failed], 129 | { 130 | Except[validLazyListPattern] :> (Message[Part::partw, state, Short[l]]; l) 131 | } 132 | ] 133 | ]; 134 | 135 | 136 | (* For efficiency reasons, these lazy list generatorss are defined by self-referential anynomous functions. Note that #0 refers to the function itself *) 137 | lazyRange[start : _ : 1, step : _ : 1] /; !TrueQ[step == 0] := Function[ 138 | lazyList[#1, #0[step + #1]] 139 | ][start]; 140 | 141 | lazyRange[start_, step_ /; TrueQ[step == 0]] := lazyConstantArray[start]; 142 | 143 | lazyPowerRange[start_, r_ /; !TrueQ[r == 1]] := Function[ 144 | lazyList[#1, #0[r * #1, r]] 145 | ][start]; 146 | 147 | lazyPowerRange[min_, r_ /; TrueQ[r == 1]] := lazyConstantArray[min] 148 | 149 | lazyNestList[f_, elem_] := Function[ 150 | lazyList[ 151 | #1, 152 | #0[f[#1], #2 + 1] 153 | ] 154 | ][elem, 1]; 155 | 156 | lazyFixedPointList[f_, elem_, sameTest : _ : SameQ] := lazyFixedPointList[f, f[elem], elem, sameTest]; 157 | lazyFixedPointList[f_, elem_, prev_, sameTest_] /; sameTest[elem, prev] := lazyList[elem, lazyList[]]; 158 | lazyFixedPointList[f_, elem_, prev_, sameTest_] := lazyList[ 159 | elem, 160 | lazyFixedPointList[f, f[elem], elem, sameTest] 161 | ]; 162 | 163 | (*lazySetState definition for lazyRange and lazyPowerRange and lazyNestList *) 164 | lazySetState[ 165 | lazyList[_, (f : Function[lazyList[#1, #0[___]]])[_, step___]], 166 | state_ 167 | ] := f[state, step]; 168 | 169 | lazyStream[stream_InputStream] := Function[ 170 | With[{ 171 | read = Read[#1] 172 | }, 173 | lazyList[ 174 | read, 175 | If[ read =!= EndOfFile, 176 | #0[#1, #2 + 1], (* Increase an iterator to make sure that ReplaceRepeated in Take doesn't stop *) 177 | lazyList[] (* return an empty lazyList to end stream *) 178 | ] 179 | ] 180 | ] 181 | ][stream, 1]; 182 | 183 | lazyConstantArray[const_] := Function[ 184 | lazyList[ 185 | const, 186 | (* Increase an iterator to make sure that ReplaceRepeated in Take doesn't stop *) 187 | #0[#1 + 1] 188 | ] 189 | ][1]; 190 | 191 | 192 | Attributes[lazyPeriodicListInternal] = {HoldFirst}; 193 | lazyPeriodicListInternal[list_, i_, max_] := lazyList[ 194 | list[[i]], 195 | lazyPeriodicListInternal[list, Mod[i + 1, max, 1], max] 196 | ]; 197 | 198 | lazyPeriodicList[Hold[list_Symbol?ListQ] | list_List] := lazyPeriodicListInternal[list, 1, Length[list]]; 199 | lazyPeriodicList[Hold[list_Symbol?ListQ] | list_List, part_Integer?Positive] := lazyPeriodicListInternal[list, 1, Length[list], part]; 200 | 201 | lazySetState[lzHead[_, HoldPattern @ lazyPeriodicListInternal[list_, _, max_, rest___]], index_Integer] := 202 | lazyPeriodicListInternal[list, Mod[index + 1 - UnitStep[index], max, 1], max, rest]; 203 | 204 | 205 | lazyPartMap[l_lazyList, indices : {__Integer}] := Module[{ 206 | sortedIndices = Sort[indices] 207 | }, 208 | Part[ 209 | FoldList[ 210 | Function[ 211 | Part[#1, {#2}] 212 | ], 213 | Part[l, sortedIndices[[{1}]]], 214 | Differences[sortedIndices] + 1 215 | ], 216 | Ordering[indices] 217 | ] 218 | ]; 219 | 220 | lazyMapThread[f_, lists : {___, _List | heldListPattern, ___}, opts : OptionsPattern[]] := lazyMapThread[ 221 | f, 222 | Replace[ 223 | lists, 224 | l : (_List | heldListPattern) :> lazyList[l], 225 | {1} 226 | ], 227 | opts 228 | ]; 229 | 230 | lazyMapThread[f_, lists : {validLazyListPattern..}, opts : OptionsPattern[]] := lazyList[ 231 | f @@ lists[[All, 1]], 232 | lazyMapThread[f, lists[[All, 2]], opts] 233 | ]; 234 | 235 | lazyTranspose[lists : {___, _List | heldListPattern, ___}, opts : OptionsPattern[]] := lazyTranspose[ 236 | Replace[ 237 | lists, 238 | l : (_List | heldListPattern) :> lazyList[l], 239 | {1} 240 | ], 241 | opts 242 | ]; 243 | 244 | lazyTranspose[list : {validLazyListPattern..}, opts : OptionsPattern[]] := lazyMapThread[List, list, opts]; 245 | 246 | lazyTruncate[lzPattern, 0] := lazyList[]; 247 | lazyTruncate[lazyList[], _] := lazyList[]; 248 | lazyTruncate[lz : lazyList[head_, tail_], int_Integer?Positive] := lazyList[ 249 | head, 250 | lazyTruncate[tail, Subtract[int, 1]] 251 | ]; 252 | lazyTruncate[lz : partitionedLazyList[head_List, tail_], int_Integer?Positive] := With[{ 253 | lHead = Length[head] 254 | }, 255 | If[ lHead >= int, 256 | partitionedLazyList[Take[head, int], lazyList[]], 257 | partitionedLazyList[head, lazyTruncate[tail, Subtract[int, lHead]]] 258 | ] 259 | ]; 260 | 261 | End[] 262 | 263 | EndPackage[] 264 | 265 | -------------------------------------------------------------------------------- /lazyLists/Kernel/lazyLists.wl: -------------------------------------------------------------------------------- 1 | ClearAll["lazyLists`*", "lazyLists`Private`*"]; 2 | 3 | Get["lazyLists`UsageMessages`"]; 4 | Get["lazyLists`lazyConstructors`"]; 5 | Get["lazyLists`partitionedLazyLists`"]; 6 | Get["lazyLists`lazySyntacticSugar`"]; 7 | Get["lazyLists`lazyTuples`"]; 8 | Get["lazyLists`DefaultsAndMessages`"]; -------------------------------------------------------------------------------- /lazyLists/Kernel/lazySyntacticSugar.wl: -------------------------------------------------------------------------------- 1 | (* ::Package:: *) 2 | 3 | BeginPackage["lazyLists`"] 4 | (* Exported symbols added here with SymbolName::usage *) 5 | 6 | Begin["`Private`"] 7 | 8 | lazyList /: Rest[lazyList[_, tail_]] := tail; 9 | lazyList /: Most[lazyList[elem_, _]] := {elem}; 10 | 11 | lazyList /: Prepend[lz_lazyList, element_] := lazyList[element, lz]; 12 | 13 | lazyList /: Append[lazyList[first_, tail_], element_] := lazyList[first, Append[tail, element]]; 14 | lazyList /: Append[lazyList[], element_] := lazyList[element, lazyList[]]; 15 | 16 | lazyList /: lazyPrependTo[lazyList[first_, lazyFiniteList[list_List, i_]], element_] := With[{ 17 | newList = Prepend[list, element] 18 | }, 19 | lazyList[first, lazyFiniteList[newList, i + 1]] 20 | ]; 21 | lazyPrependTo[lazyList[first_, lazyFiniteList[list_Symbol, i_]], element_] := ( 22 | PrependTo[list, element]; 23 | lazyList[first, lazyFiniteList[list, i + 1]] 24 | ); 25 | 26 | lazyList /: lazyAppendTo[lazyList[first_, lazyFiniteList[list_List, i_]], element_] := With[{ 27 | newList = Append[list, element] 28 | }, 29 | lazyList[first, lazyFiniteList[newList, i]] 30 | ]; 31 | lazyAppendTo[lazyList[first_, lazyFiniteList[list_Symbol, i_]], element_] := ( 32 | AppendTo[list, element]; 33 | lazyList[first, lazyFiniteList[list, i]] 34 | ); 35 | 36 | Attributes[setLazyListable] = {HoldFirst}; 37 | setLazyListable[sym_Symbol] := ( 38 | lazyList /: (expr : sym[___, lazyList[], ___]) := lazyList[]; 39 | partitionedLazyList /: sym[first___, lz_partitionedLazyList, rest___] := Function[ 40 | Thread[ 41 | Unevaluated[ 42 | Thread[Unevaluated[sym[##]]]&[##] 43 | ], 44 | partitionedLazyList 45 | ] 46 | ] @@ repartitionAll[{first, lz, rest}]; 47 | lazyList /: (expr : sym[___, _lazyList, ___]) := Thread[ 48 | Unevaluated[expr], 49 | lazyList 50 | ]; 51 | sym 52 | ); 53 | setLazyListable[{sym_Symbol, Listable}] := ( 54 | lazyList /: (expr : sym[___, lazyList[], ___]) := lazyList[]; 55 | partitionedLazyList /: (sym[first___, lz_partitionedLazyList, rest___]) := Thread[ 56 | Unevaluated[sym[##]], 57 | partitionedLazyList 58 | ]& @@ repartitionAll[{first, lz, rest}]; 59 | lazyList /: (sym[first___, lz_lazyList, rest___]) := Thread[ 60 | Unevaluated[sym[##]], 61 | lazyList 62 | ]& @@ If[ MemberQ[{first, rest}, _partitionedLazyList], 63 | repartitionAll[{first, lz, rest}], 64 | {first, lz, rest} 65 | ]; 66 | sym 67 | ); 68 | 69 | (* Set threading behaviour for lazyLists to make it possible to add and multiply them and use powers on them *) 70 | Scan[ 71 | Function[Null, setLazyListable[{#, Listable}], {HoldAll}], 72 | {Plus, Times, Power, Divide, Subtract} 73 | ]; 74 | 75 | (* Elements from lazyLists are extracted by repeatedly evaluating the next element and sowing the results *) 76 | lazyList /: Take[lz : validLazyListPattern, n_Integer?Positive] := ReleaseHold[ 77 | lazyList @@ MapAt[ 78 | First[#, {}]&, 79 | Reverse @ Reap[ 80 | Replace[ 81 | Quiet[ 82 | Block[{$IterationLimit = $lazyIterationLimit}, 83 | ReplaceRepeated[ 84 | lz, 85 | { 86 | lazyList[first_, tail_] :> (Sow[first, "take"]; tail) 87 | }, 88 | MaxIterations -> n - 1 89 | ] 90 | ], 91 | {ReplaceRepeated::rrlim} 92 | ], 93 | (* The last element should only be Sown without evaluating the tail *) 94 | lazyList[first_, tail_] :> (Sow[first, "take"]; Hold[tail]) 95 | ], 96 | "take" 97 | ], 98 | 1 99 | ] 100 | ]; 101 | 102 | lazyList /: Take[lz : validLazyListPattern, {m_Integer?Positive, n_Integer?Positive}] /; n < m := Replace[ 103 | Take[lz, {n, m}], 104 | { 105 | lazyList[list_List, rest_] :> lazyList[Reverse[list], rest] 106 | } 107 | ]; 108 | 109 | lazyList /: Take[lz : validLazyListPattern, {m_Integer?Positive, n : (_Integer?Positive | All)}] /; (n === All || n > m) := Replace[ 110 | Quiet[lz[[{m}]], {Part::partw}], 111 | { 112 | l : validLazyListPattern :> Take[l, Replace[n, int_Integer :> int - m + 1]], 113 | _ -> lazyList[] 114 | } 115 | ]; 116 | 117 | lazyList /: Take[lz : validLazyListPattern, All] := TakeWhile[lz]; 118 | 119 | lazyList /: TakeWhile[lz : validLazyListPattern, function : _ : Function[True], opts : OptionsPattern[MaxIterations -> Infinity]] := lazyList @@ MapAt[ 120 | First[#, {}]&, 121 | Reverse @ Reap[ 122 | Quiet[ 123 | Catch[ 124 | Block[{ 125 | $IterationLimit = $lazyIterationLimit, 126 | first, 127 | pattern 128 | }, 129 | pattern = If[ function === Function[True], 130 | first_, 131 | first_?function 132 | ]; 133 | ReplaceRepeated[ 134 | lz, 135 | { 136 | lazyList[pattern, tail_] :> (Sow[first, "take"]; tail), 137 | other_ :> Throw[other, "takeWhile"] 138 | }, 139 | MaxIterations -> OptionValue[MaxIterations] 140 | ] 141 | ], 142 | "takeWhile" 143 | ], 144 | {ReplaceRepeated::rrlim} 145 | ], 146 | "take" 147 | ], 148 | 1 149 | ]; 150 | 151 | lazyList /: LengthWhile[lz : validLazyListPattern, function : _ : Function[True], opts : OptionsPattern[MaxIterations -> Infinity]] := Quiet[ 152 | Block[{ 153 | $IterationLimit = $lazyIterationLimit, 154 | first, 155 | pattern, 156 | count = 0 157 | }, 158 | pattern = If[ function === Function[True], 159 | first_, 160 | first_?function 161 | ]; 162 | Replace[ 163 | Catch[ 164 | ReplaceRepeated[ 165 | {lz, First[lz]}, 166 | { 167 | {lazyList[pattern, tail_], prev_} :> (count++; {tail, first}), 168 | {other_, prev_} :> Throw[lazyList[prev, other], "lengthWhile"] 169 | }, 170 | MaxIterations -> OptionValue[MaxIterations] 171 | ], 172 | "lengthWhile" 173 | ], 174 | { 175 | (* This happens whenever $lazyIterationLimit was exceeded *) 176 | {l : validLazyListPattern, prev_} :> <|"Index" -> Infinity, "Element" -> l|>, 177 | l : validLazyListPattern :> <|"Index" -> count, "Element" -> l|> 178 | } 179 | ] 180 | ], 181 | {ReplaceRepeated::rrlim} 182 | ]; 183 | 184 | lazyList /: Part[lz : lazyList[], i_] := (Message[Part::partw, Short[i], Short[lz]]; $Failed); 185 | lazyList /: Part[lazyList[___], 0 | {0}] := lazyList; 186 | lazyList /: Part[lazyList[first_, _], 1] := first; 187 | lazyList /: Part[lz : validLazyListPattern, {1}] := lz; 188 | lazyList /: Part[lazyList[_, tail_], {2}] := tail; 189 | lazyList /: Part[lz : validLazyListPattern, {-1}] := Replace[ 190 | LengthWhile[lz, Function[True]], 191 | KeyValuePattern["Element" -> el_] :> el 192 | ]; 193 | lazyList /: Part[lz : validLazyListPattern, n : (_Integer?Positive | -1)] := First[Part[lz, {n}], $Failed]; 194 | 195 | lazyList /: Part[lz : validLazyListPattern, Span[m_Integer, n_Integer]] := Replace[ 196 | Take[lz, {m, n}], 197 | { 198 | lazyList[] | lazyList[_, lazyList[]] :> (Message[Part::partw, Max[m, n], Short[lz]]; $Failed) 199 | } 200 | ]; 201 | 202 | lazyList /: Part[lz : validLazyListPattern, Span[m_Integer, n_Integer, incr_Integer]] := Part[ 203 | lz, 204 | Range[m, n, incr] 205 | ]; 206 | 207 | lazyList /: Part[lz : validLazyListPattern, indices : {_Integer, __Integer}] /; VectorQ[indices, Positive]:= Catch[ 208 | Module[{ 209 | sortedIndices = Sort[indices], 210 | eval 211 | }, 212 | lazyList[ 213 | Part[ 214 | FoldPairList[ 215 | Function[ 216 | eval = Check[Part[#1, {#2}], Throw[$Failed, "part"], {Part::partw}]; 217 | { 218 | First[eval], (* emit the value at this position *) 219 | eval (* and return the lazyList to the next iteration *) 220 | } 221 | ], 222 | lz, 223 | Prepend[Differences[sortedIndices] + 1, First[sortedIndices]] 224 | ], 225 | Ordering[indices] 226 | ], 227 | Evaluate[eval] 228 | ] 229 | ], 230 | "part" 231 | ]; 232 | 233 | lazyList /: Part[lz : validLazyListPattern, {n_Integer?Positive}] := Replace[ 234 | Quiet[ 235 | Block[{$IterationLimit = $lazyIterationLimit}, 236 | ReplaceRepeated[ 237 | lz, 238 | { 239 | lazyList[first_, tail_] :> tail 240 | }, 241 | MaxIterations -> n - 1 242 | ] 243 | ], 244 | {ReplaceRepeated::rrlim} 245 | ], 246 | { 247 | lazyList[] :> (Message[Part::partw, n, Short[lz]]; $Failed) 248 | } 249 | ]; 250 | 251 | lazyList /: TakeDrop[lz : validLazyListPattern, args__] := With[{ 252 | newLz = Take[lz, args] 253 | }, 254 | If[ MatchQ[newLz, validLazyListPattern], 255 | {First[newLz], Rest[newLz]}, 256 | $Failed 257 | ] 258 | ]; 259 | 260 | lazyList /: Drop[lz : validLazyListPattern, args__] := With[{ 261 | newLz = Take[lz, args] 262 | }, 263 | If[ MatchQ[newLz, validLazyListPattern], 264 | Rest[newLz], 265 | $Failed 266 | ] 267 | ]; 268 | 269 | lazyList /: Map[f_, lazyList[first_, tail_]] := lazyList[ 270 | f[first], 271 | Map[f, tail] 272 | ]; 273 | 274 | lazySetState[l : lazyList[_, Map[f_, tail_]], state_] := With[{ 275 | try = Check[lazySetState[tail, state], $Failed] 276 | }, 277 | If[ MatchQ[try, validLazyListPattern], 278 | Map[f, try], 279 | l 280 | ] 281 | ]; 282 | 283 | lazyList /: MapIndexed[f_, lazyList[first_, tail_], index : (_Integer?Positive) : 1] := lazyList[ 284 | f[first, index], 285 | MapIndexed[f, tail, index + 1] 286 | ]; 287 | 288 | lazyList /: FoldList[f_, lazyList[first_, tail_]] := FoldList[f, first, tail]; 289 | lazyList /: FoldList[f_, current_, lazyList[first_, tail_]] := lazyList[ 290 | current, 291 | FoldList[f, f[current, first], tail] 292 | ]; 293 | lazyList /: FoldList[f_, current_, empty : lazyList[]] := lazyList[current, empty]; 294 | 295 | (* 296 | The True value that passes with FoldPairList is used to see if this is the first call to FoldPairList or if the process in already iterating. 297 | This is because the starting value in FoldPairList should not end up in the actual list. 298 | *) 299 | lazyList /: FoldPairList[fun_, {emit_, feed_}, True, lazyList[first_, tail_]] := lazyList[ 300 | emit, 301 | FoldPairList[fun, fun[feed, first], True, tail] 302 | ]; 303 | lazyList /: FoldPairList[fun_, {emit_, feed_}, True, empty : lazyList[]] := lazyList[emit, empty]; 304 | 305 | lazyList /: FoldPairList[fun_, {emit_, feed_}, True, lazyList[first_, tail_], red_] := lazyList[ 306 | red[{emit, feed}], 307 | FoldPairList[fun, fun[feed, first], True, tail, red] 308 | ]; 309 | lazyList /: FoldPairList[fun_, {emit_, feed_}, True, empty : lazyList[], red_] := lazyList[red[{emit, feed}], empty]; 310 | 311 | (* Patterns that start FoldPairList *) 312 | lazyList /: FoldPairList[fun_, val_, lazyList[first_, tail_]] := FoldPairList[fun, fun[val, first], True, tail]; 313 | lazyList /: FoldPairList[fun_, val_, lazyList[first_, tail_], red_] := FoldPairList[fun, fun[val, first], True, tail, red]; 314 | lazyList /: FoldPairList[fun_, val_, lazyList[], ___] := lazyList[]; 315 | 316 | lazyList /: Cases[lazyList[], _] := lazyList[] 317 | lazyList /: Cases[lz_lazyList, patt_] := Module[{ 318 | case 319 | }, 320 | (* Define helper function to match patterns faster *) 321 | case[lazyList[first : patt, tail_]] := lazyList[first, case[tail]]; 322 | case[lazyList[first_, tail_]] := case[tail]; 323 | case[lazyList[]] := lazyList[]; 324 | 325 | case[lz] 326 | ]; 327 | 328 | lazyList /: Pick[lazyList[], _, _] := lazyList[]; 329 | lazyList /: Pick[_, lazyList[], _] := lazyList[]; 330 | lazyList /: Pick[lz_lazyList, select_lazyList, patt_] := Module[{ 331 | pick 332 | }, 333 | (* Define helper function, just like with Cases *) 334 | pick[lazyList[first_, tail1_], lazyList[match : patt, tail2_]] := 335 | lazyList[first, pick[tail1, tail2]]; 336 | pick[lazyList[first_, tail1_], lazyList[first2_, tail2_]] := 337 | pick[tail1, tail2]; 338 | pick[lazyList[], _] := lazyList[]; 339 | pick[_, lazyList[]] := lazyList[]; 340 | 341 | pick[lz, select] 342 | ]; 343 | 344 | lazyList /: Select[lazyList[first_, tail_], f_] /; f[first] := lazyList[first, Select[tail, f]]; 345 | lazyList /: Select[lazyList[first_, tail_], f_] := Select[tail, f]; 346 | 347 | listOrLazyListPattern = lazyList | List; 348 | lazyCatenate[listOrLazyListPattern[]] := lazyList[]; 349 | 350 | (*Cases where the outer list is List *) 351 | lazyCatenate[list : {___, heldListPattern, ___}] := lazyCatenate @ Replace[ 352 | list, 353 | l : heldListPattern :> lazyList[l], 354 | {1} 355 | ]; 356 | 357 | lazyCatenate[list : {___, listOrLazyListPattern[], ___}] := lazyCatenate[ 358 | DeleteCases[list, listOrLazyListPattern[]] 359 | ]; 360 | lazyCatenate[lists : {(_List | _lazyList)..., _List, (_List | _lazyList)...}] := lazyCatenate[ 361 | Replace[ 362 | SequenceReplace[ 363 | lists, 364 | {l1_List, l2__List} :> Join[l1, l2] 365 | ], 366 | l_List :> lazyList[l], 367 | {1} 368 | ] 369 | ]; 370 | lazyCatenate[{lz : lzHead[_, _]}] := lz; 371 | lazyCatenate[{lazyList[first_, tail_], rest__}] := lazyList[first, lazyCatenate[{tail, rest}]]; 372 | 373 | (*Cases where the outer list is lazyList *) 374 | lazyCatenate[lazyList[listOrLazyListPattern[], tail_]] := lazyCatenate[tail]; 375 | lazyCatenate[lazyList[list_List, tail_]] := lazyCatenate[lazyList[lazyList[list], tail]]; 376 | lazyCatenate[lazyList[lazyList[first_, tail1_], tail2_]] := lazyList[first, lazyCatenate[lazyList[tail1, tail2]]]; 377 | 378 | composeMappedFunctions[lz_lazyList] := With[{ 379 | patt = Append[generatorPattern, Map] 380 | }, 381 | ReplaceRepeated[ 382 | lz, 383 | { 384 | HoldPattern @ Map[f_, (gen : patt)[fgen_, args___]] :> With[{ 385 | composition = f @* fgen (* Evaluate the composition to flatten it out if necessary *) 386 | }, 387 | gen[ 388 | composition, 389 | args 390 | ] /; True (* condition trick to make sure the With evaluates *) 391 | ] 392 | } 393 | ] 394 | ]; 395 | 396 | composeMappedFunctions[lz_partitionedLazyList] := ReplaceRepeated[ 397 | lz, 398 | { 399 | HoldPattern @ Map[fun_, Map[fgen_, tail_]] :> With[{ 400 | composition = Replace[ 401 | {fun, fgen}, 402 | { 403 | (* Don't use Composition here, because it doesn't auto-compile *) 404 | {{f_, Listable}, {g_, Listable}} :> {Function[f[g[#]]], Listable}, 405 | {f : Except[{_, Listable}], {g_, Listable}} :> {Function[f /@ g[#]], Listable}, 406 | {{f_, Listable}, g : Except[{_, Listable}]} :> {Function[f[g /@ #]], Listable}, 407 | {f_, g_} :> Function[f[g[#]]] 408 | } 409 | ] 410 | }, 411 | Map[ 412 | composition, 413 | tail 414 | ] /; True (* condition trick to make sure the With evaluates *) 415 | ] 416 | } 417 | ]; 418 | 419 | lazyList /: AllTrue[lazyList[], _] := True; 420 | lazyList /: AnyTrue[lazyList[], _] := False; 421 | lazyList /: NoneTrue[lazyList[], _] := True; 422 | 423 | MapThread[ 424 | Function[{sym, patt}, 425 | sym /: AllTrue[lz : patt, f_] := Catch[ 426 | Map[ 427 | Function[ 428 | If[ !TrueQ[f[#]], 429 | Throw[False, "lzAllTrue"], 430 | Null 431 | ] 432 | ], 433 | lz 434 | ][[-1]]; 435 | True, 436 | "lzAllTrue" 437 | ] 438 | ], 439 | { 440 | {lazyList, partitionedLazyList}, 441 | {validLazyListPattern, validPartitionedLazyListPattern} 442 | } 443 | ]; 444 | 445 | MapThread[ 446 | Function[{sym, patt}, 447 | sym /: AnyTrue[lz : patt, f_] := Catch[ 448 | Map[ 449 | Function[ 450 | If[ TrueQ[f[#]], 451 | Throw[True, "lzAnyTrue"], 452 | Null 453 | ] 454 | ], 455 | lz 456 | ][[-1]]; 457 | False, 458 | "lzAnyTrue" 459 | ] 460 | ], 461 | { 462 | {lazyList, partitionedLazyList}, 463 | {validLazyListPattern, validPartitionedLazyListPattern} 464 | } 465 | ]; 466 | 467 | MapThread[ 468 | Function[{sym, patt}, 469 | sym /: NoneTrue[lz : patt, f_] := Catch[ 470 | Map[ 471 | Function[ 472 | If[ TrueQ[f[#]], 473 | Throw[False, "lzNoneTrue"], 474 | Null 475 | ] 476 | ], 477 | lz 478 | ][[-1]]; 479 | True, 480 | "lzNoneTrue" 481 | ] 482 | ], 483 | { 484 | {lazyList, partitionedLazyList}, 485 | {validLazyListPattern, validPartitionedLazyListPattern} 486 | } 487 | ]; 488 | 489 | lazyAggregate[ 490 | lz : nonEmptyLzListPattern, 491 | {agg_, comb_}, 492 | maxItems: (_Integer?Positive | Infinity) : Infinity, 493 | bsize : (_Integer?Positive | Automatic) : Automatic 494 | ] := With[{ 495 | batchSize = Replace[ 496 | {bsize, lz}, 497 | { 498 | {i_Integer, _} :> i, 499 | {Automatic, partitionedLazyList[l_List, _]} :> Length[l], 500 | _ :> Min[100, maxItems] 501 | } 502 | ] 503 | }, 504 | With[{ 505 | n = Min[batchSize, maxItems] 506 | }, 507 | Block[{$IterationLimit = $lazyIterationLimit}, 508 | lazyAggregateInternal[ 509 | Replace[TakeDrop[lz, n], 510 | { 511 | {l_List, lz1_} :> {agg[l], lz1}, 512 | _ :> $Failed 513 | } 514 | ], 515 | {agg, comb}, 516 | Subtract[maxItems, n], 517 | If[ Head[lz] === lazyList, 518 | batchSize, 519 | bsize 520 | ] 521 | ] 522 | ] 523 | ] 524 | ]; 525 | 526 | lazyAggregateInternal[{tot_, lz_}, _, 0, _] := {tot, lz}; 527 | lazyAggregateInternal[{tot_, lazyList[]}, _, _, _] := {tot, lazyList[]}; 528 | lazyAggregateInternal[$Failed, ___] := $Failed; 529 | 530 | lazyAggregateInternal[ 531 | {tot_, lz : nonEmptyLzListPattern}, 532 | {agg_, comb_}, 533 | maxItems_, 534 | batchSize_Integer 535 | ] := With[{ 536 | n = Min[batchSize, maxItems] 537 | }, 538 | lazyAggregateInternal[ 539 | Replace[TakeDrop[lz, n], 540 | { 541 | {l_List, lz1_} :> {comb[{tot, agg[l]}], lz1}, 542 | _ :> $Failed 543 | } 544 | ], 545 | {agg, comb}, 546 | Subtract[maxItems, n], 547 | batchSize 548 | ] 549 | ]; 550 | lazyAggregateInternal[ 551 | {tot_, lz : partitionedLazyList[lst_List, _]}, 552 | {agg_, comb_}, 553 | maxItems_, 554 | Automatic 555 | ] := With[{ 556 | n = Min[Length[lst], maxItems] 557 | }, 558 | lazyAggregateInternal[ 559 | Replace[TakeDrop[lz, n], 560 | { 561 | {l_List, lz1_} :> {comb[{tot, agg[l]}], lz1}, 562 | _ :> $Failed 563 | } 564 | ], 565 | {agg, comb}, 566 | Subtract[maxItems, n], 567 | Automatic 568 | ] 569 | ]; 570 | 571 | (* 572 | (* TODO: Implement *) 573 | Scan[ 574 | Function[sym, 575 | lazyList /: HoldPattern[sym[lazyList[], ___]] := lazyList[]; 576 | lazyList /: HoldPattern[sym[lazyList[first_, tail_], n_]] := Undefined, 577 | {TakeLargest, TakeSmallest} 578 | ] 579 | ]; 580 | 581 | Scan[ 582 | Function[sym, 583 | lazyList /: HoldPattern[sym[lazyList[], ___]] := lazyList[]; 584 | With[{ 585 | smallOrLarge = Replace[sym, {TakeLargestBy -> TakeLargest, TakeSmallestBy -> TakeSmallest}] 586 | }, 587 | lazyList /: HoldPattern[sym[lz : validLazyListPattern, f_, n_]] := smallOrLarge[Map[f, lz], n] 588 | ], 589 | {TakeLargestBy, TakeSmallestBy} 590 | ] 591 | ]; 592 | *) 593 | End[] 594 | 595 | EndPackage[] 596 | 597 | -------------------------------------------------------------------------------- /lazyLists/Kernel/lazyTuples.wl: -------------------------------------------------------------------------------- 1 | (* Wolfram Language Package *) 2 | 3 | (* Created by the Wolfram Workbench 18-Sep-2018 *) 4 | Quiet[Needs["Combinatorica`"]]; 5 | BeginPackage["lazyLists`", {"Combinatorica`"}] 6 | (* Exported symbols added here with SymbolName::usage *) 7 | 8 | Begin["`Private`"] 9 | (* Implementation of the package *) 10 | 11 | (* Source of decompose and basis: https://mathematica.stackexchange.com/a/153609/43522 *) 12 | basis[lengths : {__Integer}] := ( 13 | basis[lengths] = Reverse @ FoldList[Times, 1, Reverse @ Rest @ lengths] 14 | ); 15 | 16 | (* Compilation only works for Machine integers *) 17 | decompose[base : {__Integer}] /; AllTrue[base, Developer`MachineIntegerQ] := ( 18 | decompose[base] = Compile[{ 19 | {n, _Integer, 1} 20 | }, 21 | Module[{ 22 | c = n - 1, (* I pick an offset here to make sure that n enumerates from 1 instead of 0 *) 23 | q 24 | }, 25 | 1 + Table[ (* And added 1 so it's not necessary to do so later on *) 26 | q = Quotient[c, i]; 27 | c = Mod[c, i]; 28 | q, 29 | {i, base} 30 | ] 31 | ], 32 | RuntimeAttributes -> {Listable} 33 | ] 34 | ); 35 | 36 | decompose[base : {__Integer}] := ( 37 | decompose[base] = Module[{ 38 | baseVar = base 39 | }, 40 | Function[ 41 | Block[{ (* Block is faster than Module *) 42 | q, 43 | r = Subtract[#, 1] 44 | }, 45 | 1 + Table[ 46 | q = Quotient[r, i]; 47 | r = Mod[q, i]; 48 | q, 49 | {i, baseVar} 50 | ] 51 | ] 52 | ] 53 | ] 54 | ); 55 | 56 | rangeTuplesAtPositions[lengths : {__Integer}] := decompose[basis[lengths]]; 57 | 58 | (* lazyList that generates the elements of Tuples[Range /@ lengths] *) 59 | Options[indexLazyList] = { 60 | "PartitionSize" -> 10, 61 | "Start" -> 1 62 | }; 63 | 64 | indexLazyList[lengths : {__Integer}, opts : OptionsPattern[]] := With[{ 65 | start = Replace[OptionValue["Start"], Except[_Integer] :> 1], 66 | partition = Replace[OptionValue["PartitionSize"], Except[_Integer] :> 1] 67 | }, 68 | Map[ 69 | {rangeTuplesAtPositions[lengths], Listable}, 70 | lazyTruncate[partitionedLazyRange[start, 1, partition], Times @@ lengths] 71 | ] 72 | ]; 73 | 74 | (* 75 | Converts elements from 76 | Tuples[Range /@ elements /@ elementLists] 77 | to elements from 78 | Tuples[elementLists] 79 | *) 80 | bulkExtractElementsUsingIndexList[elementLists_List | elementLists_Symbol | Hold[elementLists_Symbol]] := 81 | Function[ 82 | Transpose[ 83 | Developer`ToPackedArray[ 84 | MapThread[Part, {elementLists, #}] 85 | ] 86 | ] 87 | ]; 88 | 89 | (* 90 | Converts elements from 91 | Tuples[Range @ Length @ elementLists], tupLength] 92 | to elements from 93 | Tuples[elementLists, tupLength] 94 | Note that the tupLength argument only serves to distinguish the two use cases of bulkExtractElementsUsingIndexList 95 | *) 96 | 97 | bulkExtractElementsUsingIndexList[elementList_List | elementList_Symbol | Hold[elementList_Symbol], tupLength_Integer] := 98 | Function[Transpose[Part[elementList, #]& /@ #]]; 99 | 100 | Options[lazyTuples] = Options[indexLazyList]; 101 | lazyTuples[ 102 | elementLists_List | Hold[elementLists_Symbol], 103 | opts : OptionsPattern[] 104 | ] /; MatchQ[elementLists, {{__}..}] := With[{ 105 | lengths = Length /@ elementLists 106 | }, 107 | composeMappedFunctions @ Map[ 108 | { 109 | bulkExtractElementsUsingIndexList[Unevaluated[elementLists]], 110 | Listable 111 | }, 112 | indexLazyList[lengths, opts] 113 | ] 114 | ]; 115 | 116 | (* Effectively equal to lazyTuples[Range /@ lengths] *) 117 | lazyTuples[lengths : {__Integer}, opts : OptionsPattern[]] := composeMappedFunctions @ Map[ 118 | { 119 | Transpose[#]&, 120 | Listable 121 | }, 122 | indexLazyList[lengths, opts] 123 | ] 124 | 125 | 126 | lazyTuples[ 127 | elementList_List | Hold[elementList_Symbol], 128 | tupLength_Integer?Positive, 129 | opts : OptionsPattern[] 130 | ] /; And[ 131 | MatchQ[elementList, {__}], 132 | UnsameQ[elementList, Range @ Length @ elementList] 133 | ] := composeMappedFunctions @ Map[ 134 | { 135 | bulkExtractElementsUsingIndexList[Unevaluated[elementList], tupLength], 136 | Listable 137 | }, 138 | indexLazyList[ConstantArray[Length[elementList], tupLength], opts] 139 | ]; 140 | 141 | (* If elementList is just a Range of integers, there's no need to look up the elements from elementList *) 142 | lazyTuples[ 143 | elementList_List | Hold[elementList_Symbol], 144 | tupLength_Integer?Positive, 145 | opts : OptionsPattern[] 146 | ] /; SameQ[elementList, Range @ Length @ elementList] := lazyTranspose[ 147 | indexLazyList[ConstantArray[Length[elementList], tupLength], opts] 148 | ]; 149 | 150 | (* 151 | Modify the function Combinatorica`Private`NC from Combinatorica, which is a compiled function that underlies NextComposition from that package. 152 | Instead of returning tuples with integers >= 0, nextIntegerTuple returns tuples of integers >= 1. 153 | Furthermore, Combinatorica`NextComposition loops back from {n, 0, ..., 0} to {0, ..., 0, n}, 154 | while nextIntegerTuple jumps from {n, 1, ..., 1} to {1, ..., 1, n + 1}. 155 | *) 156 | nextIntegerTuple = Compile[{ 157 | {tuple, _Integer, 1} 158 | }, 159 | Module[{ 160 | list = tuple - 1, 161 | first 162 | }, 163 | first = First[list]; 164 | If[ first == Total[list], 165 | Append[Table[1, {Length[list] - 1}], first + 2], 166 | 1 + Combinatorica`Private`NC[list] 167 | ] 168 | ], 169 | CompilationOptions -> { 170 | "InlineExternalDefinitions" -> True, 171 | "InlineCompiledFunctions" -> True 172 | } 173 | ]; 174 | 175 | (* Generates all tuples of natural numbers of length tupLength *) 176 | lazyTuples[tupLength_Integer, staringTuple : ({__} | Automatic) : Automatic, opt : OptionsPattern[]] := partitionedLazyNestList[ 177 | nextIntegerTuple, 178 | Replace[staringTuple, Automatic :> ConstantArray[1, tupLength]], 179 | OptionValue["PartitionSize"] 180 | ]; 181 | 182 | 183 | End[] 184 | 185 | EndPackage[] 186 | 187 | -------------------------------------------------------------------------------- /lazyLists/Kernel/partitionedLazyLists.wl: -------------------------------------------------------------------------------- 1 | (* Wolfram Language Package *) 2 | 3 | (* Created by the Wolfram Workbench 18-Sep-2018 *) 4 | BeginPackage["lazyLists`"] 5 | (* Exported symbols added here with SymbolName::usage *) 6 | 7 | 8 | Begin["`Private`"] 9 | (* Implementation of the package *) 10 | 11 | partitionedLazyList::cannotPartition = "Cannot partition lazyList `1` because not all elements are lists. Empty lazyList was returned"; 12 | 13 | Attributes[partitionedLazyList] = {HoldRest}; 14 | partitionedLazyList[] := lazyList[]; 15 | partitionedLazyList[lazyList[], ___] := lazyList[]; 16 | partitionedLazyList[{Shortest[first___], endOfLazyList, ___}, ___] := partitionedLazyList[{first}, lazyList[]]; 17 | partitionedLazyList[$Failed] := $Failed; 18 | partitionedLazyList[lz : lazyList[Except[_List], _]] := ( 19 | Message[partitionedLazyList::cannotPartition, Short[lz]]; 20 | lazyList[] 21 | ); 22 | partitionedLazyList[{}, tail_] := tail; 23 | partitionedLazyList[list_List] := partitionedLazyList[list, lazyList[]]; 24 | partitionedLazyList[lazyList[list_List, tail_]] := partitionedLazyList[list, partitionedLazyList[tail]]; 25 | 26 | partitionedLazyList /: Prepend[partitionedLazyList[list_List, tail_], newElem_] := partitionedLazyList[Prepend[list, newElem], tail]; 27 | 28 | partitionedLazyList /: First[partitionedLazyList[{elem_, ___}, _], ___] := elem; 29 | partitionedLazyList /: Most[partitionedLazyList[list_List, _]] := list; 30 | partitionedLazyList /: Rest[partitionedLazyList[{_}, tail_]] := tail; 31 | partitionedLazyList /: Rest[partitionedLazyList[{_, rest__}, tail_]] := partitionedLazyList[{rest}, tail]; 32 | 33 | partitionedLazyRange[partition_Integer?Positive] := partitionedLazyRange[1, 1, partition]; 34 | partitionedLazyRange[start_, partition_Integer?Positive] := partitionedLazyRange[start, 1, partition]; 35 | 36 | partitionedLazyRange[start_, step_ /; TrueQ[step == 0], partition_Integer?Positive] := With[{ 37 | arr = ConstantArray[start, partition] 38 | }, 39 | Function[ 40 | partitionedLazyList[ 41 | arr, 42 | #0[#1 + 1] 43 | ] 44 | ][1] 45 | ]; 46 | 47 | partitionedLazyRange[start_?NumericQ, step_?NumericQ, partition_Integer?Positive] := With[{ 48 | stepMult = Subtract[partition, 1] 49 | }, 50 | Function[ 51 | With[{next = #1 + step * stepMult}, 52 | partitionedLazyList[ 53 | Range[#1, next, step], 54 | #0[next + step] 55 | ] 56 | ] 57 | ][start] 58 | ]; 59 | 60 | partitionedLazyRange[start_, step_, partition_Integer?Positive] := partitionedLazyList[ 61 | lazyRange[ 62 | start + step * Range[0, partition - 1], 63 | partition * step 64 | ] 65 | ]; 66 | 67 | partitionedLazyNestList[fun_, elem_, partition_Integer?Positive] := Function[ 68 | With[{ 69 | nestList = NestList[fun, #1, partition - 1] 70 | }, 71 | With[{ 72 | last = Last[nestList] 73 | }, 74 | partitionedLazyList[ 75 | nestList, 76 | #0[fun[last], #2 + 1] 77 | ] 78 | ] 79 | ] 80 | ][elem, 1]; 81 | 82 | lazyPartition[lazyList[] | {}, ___] := lazyList[]; 83 | 84 | lazyPartition[lazyList[fst_, lazyList[rest_List]], newPart_Integer?Positive] := With[{ 85 | newRest = Drop[rest, UpTo[newPart - 1]] 86 | }, 87 | partitionedLazyList[ 88 | Prepend[Take[rest, UpTo[newPart - 1]], fst], 89 | lazyPartition[newRest, newPart] 90 | ] 91 | ]; 92 | 93 | lazyPartition[lzHead[_, HoldPattern @ lazyFiniteList[list_, ind_, p0 : _Integer : 1]], newPart_Integer?Positive] := 94 | lazyFiniteList[list, ind - p0, newPart]; 95 | lazyPartition[lzHead[_, HoldPattern @ lazyPeriodicListInternal[list_, ind_, max_, p0 : _Integer : 1]], newPart_Integer?Positive] := 96 | lazyPeriodicListInternal[list, ind - p0, max, newPart]; 97 | 98 | lazyPartition[partitionedLazyList[list_, lazyPartition[tail_, _]], partition_Integer?Positive] := Take[ 99 | partitionedLazyList[list, lazyPartition[tail, partition]], 100 | partition 101 | ]; 102 | 103 | lazyPartition[lz : lzPattern, partition_Integer?Positive] := Replace[ 104 | Take[lz, partition], 105 | { 106 | lazyList[list_List, lazyList[]] :> partitionedLazyList[list, lazyList[]], 107 | (lazyList | partitionedLazyList)[list_List, tail : Except[lazyList[]]] :> partitionedLazyList[list, lazyPartition[tail, partition]] 108 | } 109 | ]; 110 | 111 | With[{ 112 | msgs = {Take::take, Take::normal} 113 | }, 114 | lazyFiniteList[list_, ind_, partition_] := Quiet[ 115 | Check[ 116 | With[{ 117 | nextIndex = ind + partition 118 | }, 119 | partitionedLazyList[ 120 | Take[list, {ind, UpTo[ind + partition - 1]}], 121 | lazyFiniteList[list, nextIndex, partition] 122 | ] 123 | ], 124 | lazyList[], 125 | msgs 126 | ], 127 | msgs 128 | ] 129 | ]; 130 | 131 | lazyPartition[Hold[list_Symbol?ListQ] | list_List, n_Integer?Positive] := lazyFiniteList[list, 1, n]; 132 | 133 | lazyPeriodicListInternal[list_, i_, max_, part_] := partitionedLazyList[ 134 | Part[ 135 | list, 136 | Mod[Range[i, i + part - 1], max, 1] 137 | ], 138 | lazyPeriodicListInternal[list, Mod[i + part, max, 1], max, part] 139 | ]; 140 | 141 | parseTakeSpec[n : (_Integer?Positive | All)] := {1, n, 1}; 142 | parseTakeSpec[{m_Integer?Positive, n_Integer?Positive}] := Append[Sort[{m, n}], 1]; 143 | parseTakeSpec[{m_Integer?Positive, All}] := {m, All, 1}; 144 | parseTakeSpec[{m_Integer?Positive, n_Integer?Positive, step_Integer}] /; step != 0 && m > n := { 145 | n + Mod[Subtract[m, n], Abs[step]], (* Make sure take starts at the right value to end up exactly at m *) 146 | m, 147 | -step 148 | } 149 | 150 | parseTakeSpec[{m_Integer?Positive, n_Integer?Positive, step_Integer}] /; step != 0 && m <= n := {m, n, step}; 151 | parseTakeSpec[spec : {_Integer?Positive, All, _Integer?Positive}] := spec; 152 | parseTakeSpec[___] := $Failed 153 | 154 | partitionedLazyList /: Take[ 155 | partitionedLazyList[list_List, tail_], 156 | spec : _Integer | {_Integer, ___Integer} 157 | ] := With[{ 158 | maxIndex = Max @ Replace[spec, {m_, n_, _} :> {m, n}] 159 | }, 160 | partitionedLazyList[ 161 | Take[list, spec], 162 | Evaluate @ partitionedLazyList[Drop[list, maxIndex], tail] 163 | ] /; Length[list] >= maxIndex 164 | ]; 165 | 166 | partitionedLazyList /: Take[lz : validPartitionedLazyListPattern, {m_Integer?Positive, n_Integer?Positive, step : _Integer : 1}] /; n < m := Replace[ 167 | Take[lz, parseTakeSpec[{m, n, step}]], 168 | { 169 | partitionedLazyList[list_List, rest_] :> partitionedLazyList[Reverse[list], rest] 170 | } 171 | ]; 172 | 173 | partitionedLazyList /: Take[lz : validPartitionedLazyListPattern, spec_] := With[{ 174 | parsedSpec = parseTakeSpec[spec] 175 | }, 176 | Take[lz, parsedSpec] /; parsedSpec =!= $Failed && parsedSpec =!= spec 177 | ]; 178 | 179 | partitionedLazyList /: Take[ 180 | lz : validPartitionedLazyListPattern, 181 | {start : Except[1, (_Integer?Positive)], stop : (_Integer?Positive | All), step_Integer?Positive} 182 | ] := With[{ 183 | advancedLz = Quiet[Part[lz, {start}], {Part::partw}] 184 | }, 185 | If[ MatchQ[advancedLz, validPartitionedLazyListPattern], 186 | Take[ 187 | advancedLz, 188 | { 189 | 1, 190 | Replace[stop, {int_Integer :> int - start + 1}], 191 | step 192 | } 193 | ], 194 | lazyList[] 195 | ] 196 | ]; 197 | 198 | partitionedLazyList /: Take[ 199 | partLz : validPartitionedLazyListPattern, 200 | {1, n : (_Integer?Positive | All), step_Integer?Positive} 201 | ] := partitionedLazyList @@ MapAt[ 202 | Catenate[First[#, {}]]&, 203 | Reap[ 204 | Catch[ 205 | Block[{ 206 | $IterationLimit = $lazyIterationLimit, 207 | count = n, 208 | offset = 0, 209 | result, 210 | take, 211 | len 212 | }, 213 | ReplaceRepeated[ 214 | partLz, 215 | { 216 | lazyList[] :> Throw[ 217 | lazyList[], 218 | "takePartitioned" 219 | ], 220 | partitionedLazyList[l : Except[_List], _] :> ( 221 | Message[partitionedLazyList::cannotPartition, Short[l]]; 222 | lazyList[] 223 | ), 224 | Switch[ {n, step}, 225 | {All, 1}, 226 | partitionedLazyList[list_List, tail_] :> ( 227 | Sow[list, "results"]; 228 | tail 229 | ), 230 | {All, _}, 231 | partitionedLazyList[list_List, tail_] :> ( 232 | If[Length[list] > offset, 233 | Sow[Part[list, 1 + offset ;; All ;; step], "results"] 234 | ]; 235 | offset = Mod[Subtract[offset, Length[list]], step]; 236 | tail 237 | ), 238 | {_, 1}, 239 | partitionedLazyList[ 240 | list_List?(Function[(len = Length[#]) < count]), 241 | tail_ 242 | ] :> ( 243 | Sow[list, "results"]; 244 | count -= len; 245 | tail 246 | ), 247 | _, 248 | partitionedLazyList[ 249 | list_List?(Function[(len = Length[#]) < count]), 250 | tail_ 251 | ] :> ( 252 | If[ TrueQ[len > offset], 253 | Sow[Part[list, 1 + offset ;; All ;; step], "results"] 254 | ]; 255 | count -= len; 256 | offset = Mod[Subtract[offset, len], step]; 257 | tail 258 | ) 259 | ], 260 | If[ n === All, 261 | Nothing, 262 | partitionedLazyList[list_List, tail_] :> ( 263 | Sow[Part[list, 1 + offset ;; count ;; step], "results"]; 264 | Throw[ 265 | partitionedLazyList[Drop[list, count], tail], 266 | "takePartitioned" 267 | ] 268 | ) 269 | ] 270 | }, 271 | MaxIterations -> DirectedInfinity[1] 272 | ] 273 | ], 274 | "takePartitioned" 275 | ], 276 | "results" 277 | ][[{2, 1}]], 278 | 1 279 | ]; 280 | 281 | partitionedLazyList /: TakeWhile[ 282 | partLz : validPartitionedLazyListPattern, 283 | function : _ : Function[True], 284 | opts : OptionsPattern[MaxIterations -> Infinity] 285 | ] := partitionedLazyList @@ MapAt[ 286 | Catenate[First[#, {}]]&, 287 | Reverse @ Reap[ 288 | Quiet[ 289 | Catch[ 290 | Block[{ 291 | $IterationLimit = $lazyIterationLimit, 292 | first, 293 | ind 294 | }, 295 | ReplaceRepeated[ 296 | partLz, 297 | { 298 | If[ function === Function[True] 299 | , 300 | partitionedLazyList[list_List, tail_] :> ( 301 | Sow[list, "partTakeWhile"]; 302 | tail 303 | ) 304 | , 305 | partitionedLazyList[list_List, tail_] :> ( 306 | ind = LengthWhile[list, function]; 307 | If[ ind === Length[list] 308 | , 309 | Sow[list, "partTakeWhile"]; 310 | tail 311 | , 312 | Sow[Take[list, ind], "partTakeWhile"]; 313 | Throw[ 314 | partitionedLazyList[Drop[list, ind], tail], 315 | "takeWhile" 316 | ] 317 | ] 318 | ) 319 | ], 320 | other_ :> Throw[other, "takeWhile"] 321 | }, 322 | MaxIterations -> OptionValue[MaxIterations] 323 | ] 324 | ], 325 | "takeWhile" 326 | ], 327 | {ReplaceRepeated::rrlim} 328 | ], 329 | "partTakeWhile" 330 | ], 331 | 1 332 | ]; 333 | 334 | partitionedLazyList /: LengthWhile[ 335 | lz : partitionedLazyList[{___, el_}, _], 336 | function : _ : Function[True], 337 | opts : OptionsPattern[MaxIterations -> Infinity] 338 | ] := Quiet[ 339 | Block[{ 340 | $IterationLimit = $lazyIterationLimit, 341 | count = 0, 342 | ind 343 | }, 344 | Replace[ 345 | Catch[ 346 | ReplaceRepeated[ 347 | {lz, el}, 348 | { 349 | If[ function === Function[True] 350 | , 351 | {partitionedLazyList[list : {___, elem_}, tail_], prev_} :> ( 352 | count += Length[list]; 353 | {tail, elem} 354 | ) 355 | , 356 | {partitionedLazyList[list : {___, elem_}, tail_], prev_} :> ( 357 | count += ( 358 | ind = LengthWhile[list, function] 359 | ); 360 | Switch[ ind, 361 | Length[list], 362 | {tail, elem}, 363 | 0, 364 | Throw[ 365 | partitionedLazyList[{prev}, tail], 366 | "lengthWhile" 367 | ], 368 | _, 369 | Throw[ 370 | partitionedLazyList[Drop[list, ind - 1], tail], 371 | "lengthWhile" 372 | ] 373 | ] 374 | ) 375 | ], 376 | {other_, prev_} :> Throw[partitionedLazyList[{prev}, other], "lengthWhile"] 377 | }, 378 | MaxIterations -> OptionValue[MaxIterations] 379 | ], 380 | "lengthWhile" 381 | ], 382 | { 383 | (* This happens whenever $lazyIterationLimit was exceeded *) 384 | {l : validPartitionedLazyListPattern, prev_} :> <|"Index" -> Infinity, "Element" -> l|>, 385 | l : validPartitionedLazyListPattern :> <|"Index" -> count, "Element" -> l|> 386 | } 387 | ] 388 | ], 389 | {ReplaceRepeated::rrlim} 390 | ]; 391 | 392 | partitionedLazyList /: Part[_partitionedLazyList, {0} | 0] := partitionedLazyList; 393 | partitionedLazyList /: Part[partLz : validPartitionedLazyListPattern, 1] := First[partLz]; 394 | partitionedLazyList /: Part[partLz : validPartitionedLazyListPattern, {1}] := partLz; 395 | partitionedLazyList /: Part[partLz : validPartitionedLazyListPattern, n : (_Integer?Positive | -1)] := First[Part[partLz, {n}], $Failed]; 396 | partitionedLazyList /: Part[partitionedLazyList[list : {_, ___}, tail_], {n_Integer?Positive}] /; n <= Length[list] := 397 | partitionedLazyList[Drop[list, n - 1], tail]; 398 | partitionedLazyList /: Part[lz : validPartitionedLazyListPattern, {-1}] := Replace[ 399 | LengthWhile[lz, Function[True]], 400 | KeyValuePattern["Element" -> el_] :> el 401 | ]; 402 | 403 | 404 | partitionedLazyList /: Part[partLz : validPartitionedLazyListPattern, span_Span] := Take[partLz, List @@ span]; 405 | 406 | partitionedLazyList /: Part[partLz : validPartitionedLazyListPattern, {n_Integer?Positive}] := Catch[ 407 | Block[{ 408 | $IterationLimit = $lazyIterationLimit, 409 | count = n, 410 | length 411 | }, 412 | ReplaceRepeated[ 413 | partLz, 414 | { 415 | lazyList[] :> Throw[ 416 | lazyList[], 417 | "partPartitioned" 418 | ], 419 | partitionedLazyList[l : Except[_List], _] :> ( 420 | Message[partitionedLazyList::cannotPartition, Short[l]]; 421 | lazyList[] 422 | ), 423 | partitionedLazyList[ 424 | list_List?(Function[(length = Length[#]) < count]), tail_] :> ( 425 | count -= length; 426 | tail 427 | ), 428 | partitionedLazyList[l_List, tail_] :> ( 429 | Throw[ 430 | partitionedLazyList[ 431 | l[[{count}]], 432 | Evaluate @ partitionedLazyList[Drop[l, count], tail] 433 | ], 434 | "partPartitioned" 435 | ] 436 | ) 437 | }, 438 | MaxIterations -> DirectedInfinity[1] 439 | ] 440 | ], 441 | "partPartitioned" 442 | ]; 443 | 444 | partitionedLazyList /: Part[lz : validPartitionedLazyListPattern, indices : {_Integer, __Integer}] /; VectorQ[indices, Positive]:= Catch[ 445 | Module[{ 446 | sortedIndices = Sort[indices], 447 | eval 448 | }, 449 | partitionedLazyList[ 450 | Part[ 451 | FoldPairList[ 452 | Function[ 453 | eval = Check[Part[#1, {#2}], Throw[$Failed, "part"], {Part::partw}]; 454 | { 455 | First[eval], (* emit the value at this position *) 456 | eval (* and return the lazyList to the next iteration *) 457 | } 458 | ], 459 | lz, 460 | Prepend[Differences[sortedIndices] + 1, First[sortedIndices]] 461 | ], 462 | Ordering[indices] 463 | ], 464 | Evaluate[eval] 465 | ] 466 | ], 467 | "part" 468 | ]; 469 | 470 | partitionedLazyList /: TakeDrop[lz : validPartitionedLazyListPattern, args__] := With[{ 471 | newLz = Take[lz, args] 472 | }, 473 | If[ MatchQ[newLz, validPartitionedLazyListPattern], 474 | {Most[newLz], Last[newLz]}, 475 | $Failed 476 | ] 477 | ]; 478 | 479 | partitionedLazyList /: Drop[lz : validPartitionedLazyListPattern, args__] := With[{ 480 | newLz = Take[lz, args] 481 | }, 482 | If[ MatchQ[newLz, validPartitionedLazyListPattern], 483 | Last[newLz], 484 | $Failed 485 | ] 486 | ]; 487 | 488 | (* 489 | The function specification {fun, Listable} signals that fun is listable and should be applied directly to the list. 490 | Note that it's up to the user to ensure that fun is actually listable 491 | *) 492 | partitionedLazyList /: Map[{fun_, Listable}, partitionedLazyList[first_, tail_]] := partitionedLazyList[ 493 | fun[first], 494 | Map[{fun, Listable}, tail] 495 | ]; 496 | partitionedLazyList /: Map[fun_, partitionedLazyList[first_, tail_]] := partitionedLazyList[ 497 | fun /@ first, 498 | Map[fun, tail] 499 | ]; 500 | 501 | partitionedLazyList /: MapIndexed[fun_, partitionedLazyList[first_, tail_], index : (_Integer?Positive) : 1] := With[{ 502 | length = Length[first] 503 | }, 504 | partitionedLazyList[ 505 | MapThread[fun, {first, Range[index, index + length - 1]}], 506 | MapIndexed[fun, tail, index + length] 507 | ] 508 | ]; 509 | 510 | partitionedLazyList /: FoldList[fun_, partitionedLazyList[{elem_, rest___}, tail_]] := FoldList[ 511 | fun, 512 | elem, 513 | partitionedLazyList[{rest}, tail] 514 | ]; 515 | 516 | partitionedLazyList /: FoldList[fun_, current_, partitionedLazyList[first_List, tail_]] := With[{ 517 | fold = FoldList[fun, current, first] 518 | }, 519 | With[{newTail = tail}, 520 | If[ newTail === lazyList[], 521 | partitionedLazyList[ 522 | fold, 523 | lazyList[] 524 | ], 525 | If[ fold === {}, (* If fold has length 0, the last element is assumed to have been Nothing *) 526 | FoldList[fun, Nothing, newTail], 527 | With[{last = Last[fold]}, 528 | partitionedLazyList[ 529 | Most @ fold, (* The last element of fold will be added in the next iteration *) 530 | FoldList[fun, last, newTail] 531 | ] 532 | ] 533 | ] 534 | ] 535 | ] 536 | ]; 537 | 538 | partitionedLazyList /: FoldPairList[fun_, current_, partitionedLazyList[first_List, tail_], g : _ : First] := Block[{ 539 | state, 540 | fold 541 | }, 542 | fold = FoldPairList[fun, current, first, Function[state = Last[#]; g[#]]]; 543 | With[{ 544 | st = state 545 | }, 546 | partitionedLazyList[ 547 | fold, 548 | FoldPairList[fun, st, tail, g] 549 | ] 550 | ] 551 | ]; 552 | 553 | partitionedLazyList /: Cases[partitionedLazyList[list_List, tail_], patt_] := partitionedLazyList[ 554 | Cases[list, patt], 555 | Cases[tail, patt] 556 | ]; 557 | 558 | partitionedLazyList /: Pick[ 559 | partitionedLazyList[first_List, tail1_], 560 | partitionedLazyList[select_List, tail2_], 561 | patt_ 562 | ] := With[{ 563 | minLength = Min[Length /@ {first, select}] 564 | }, 565 | With[{ 566 | rest1 = Drop[first, minLength], 567 | rest2 = Drop[select, minLength] 568 | }, 569 | partitionedLazyList[ 570 | Pick[Take[first, minLength], Take[select, minLength], patt], 571 | Pick[ 572 | partitionedLazyList[rest1, tail1], 573 | partitionedLazyList[rest2, tail2], 574 | patt 575 | ] 576 | ] 577 | ] 578 | ]; 579 | 580 | partitionedLazyList /: Select[partitionedLazyList[first_List, tail_], fun_] := partitionedLazyList[ 581 | Select[first, fun], 582 | Select[tail, fun] 583 | ]; 584 | 585 | lazyCatenate[lists : {___, __List, partitionedLazyList[_, _], rest___}] := 586 | lazyCatenate[ 587 | SequenceReplace[ 588 | lists, 589 | {l1__List, partitionedLazyList[l2_List, tail_]} :> partitionedLazyList[Join[l1, l2], tail] 590 | ] 591 | ]; 592 | lazyCatenate[{fst__partitionedLazyList, lists__List}] := lazyCatenate[{fst, partitionedLazyList[Join[lists], lazyList[]]}]; 593 | 594 | lazyCatenate[{partitionedLazyList[list_List, tail_], rest__partitionedLazyList}] := partitionedLazyList[list, lazyCatenate[{tail, rest}]]; 595 | 596 | Options[repartitionAll] = { 597 | "RepartitionFunction" -> Max 598 | }; 599 | repartitionAll[exprs : {___, lazyList[], ___}, ___] := Replace[ 600 | exprs, 601 | { 602 | lz : lzPattern -> lazyList[] 603 | }, 604 | {1} 605 | ]; 606 | repartitionAll[exprs_List, opts : OptionsPattern[]] := With[{ 607 | lengths = Cases[exprs, partitionedLazyList[lst_List, ___] :> Length[lst]] 608 | }, 609 | If[ SameQ @@ lengths && FreeQ[exprs, _lazyList, {1}, Heads -> False], 610 | exprs, 611 | repartitionAll[exprs, OptionValue["RepartitionFunction"][lengths]] 612 | ] /; MatchQ[lengths, {__Integer}] 613 | ]; 614 | repartitionAll[exprs_List, newLength_Integer?Positive] := repartitionAll[ 615 | Replace[ 616 | exprs, 617 | { 618 | lz : partitionedLazyList[_, _lazyPartition] | _lazyList :> lazyPartition[lz, newLength], 619 | partLz_partitionedLazyList :> Take[partLz, newLength] 620 | }, 621 | {1} 622 | ], 623 | "RepartitionFunction" -> Min 624 | ]; 625 | repartitionAll[other_, ___] := other; 626 | 627 | Options[lazyMapThread] = Options[repartitionAll]; 628 | lazyMapThread[fun_, lists : {lzHead[_, _]..}, opts : OptionsPattern[]] := With[{ 629 | repartitioned = repartitionAll[lists, opts] 630 | }, 631 | With[{ 632 | heads = repartitioned[[All, 1]], 633 | tails = repartitioned[[All, 2]] 634 | }, 635 | partitionedLazyList[ 636 | MapThread[fun, heads], 637 | lazyMapThread[ 638 | fun, 639 | tails 640 | ] 641 | ] 642 | ] /; FreeQ[repartitioned, lazyList[], {1}, Heads -> False] 643 | ]; 644 | 645 | Options[lazyTranspose] = Options[repartitionAll]; 646 | lazyTranspose[lists : {lzHead[_, _]..}, opts : OptionsPattern[]] := lazyMapThread[List, lists, opts]; 647 | lazyTranspose[ 648 | lz : partitionedLazyList[lists : {{___}..}, _] 649 | ] /; SameQ @@ (Length /@ lists) := Map[{Transpose, Listable}, lz]; 650 | 651 | End[] 652 | 653 | EndPackage[] 654 | 655 | -------------------------------------------------------------------------------- /lazyLists/PacletInfo.wl: -------------------------------------------------------------------------------- 1 | (* Paclet Info File *) 2 | 3 | (* created 2019/07/18*) 4 | 5 | Paclet[ 6 | Name -> "lazyLists", 7 | Version -> "1.1", 8 | MathematicaVersion -> "12.0+", 9 | Description -> "Mathematica implementation of Haskell-style lazy lists.", 10 | Creator -> "Sjoerd Smit", 11 | Extensions -> { 12 | {"Kernel", Root -> "Kernel", Context -> "lazyLists`"} 13 | } 14 | ] 15 | --------------------------------------------------------------------------------