├── .envrc ├── .ghcid ├── .gitattributes ├── .github └── workflows │ └── publish.yaml ├── .gitignore ├── .hlint.yaml ├── .vscode ├── extensions.json └── settings.json ├── LICENSE ├── README.md ├── ema-template.cabal ├── flake.lock ├── flake.nix ├── justfile ├── src └── Main.hs └── static ├── logo.svg └── tailwind.css /.envrc: -------------------------------------------------------------------------------- 1 | watch_file *.cabal 2 | use flake -------------------------------------------------------------------------------- /.ghcid: -------------------------------------------------------------------------------- 1 | --warnings -T Main.main --setup ":set args run --port=9001" 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | flake.lock linguist-generated=true 2 | static/tailwind.css linguist-generated=true 3 | -------------------------------------------------------------------------------- /.github/workflows/publish.yaml: -------------------------------------------------------------------------------- 1 | name: "Build and maybe publish site" 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request: 7 | jobs: 8 | ema: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v4 12 | - uses: DeterminateSystems/nix-installer-action@main 13 | - uses: DeterminateSystems/magic-nix-cache-action@main 14 | - name: Build sources & site 🔧 15 | run: | 16 | nix build .#site-github -j auto 17 | - name: Deploy to gh-pages 🚀 18 | uses: peaceiris/actions-gh-pages@v3 19 | if: github.ref == 'refs/heads/master' 20 | with: 21 | github_token: ${{ secrets.GITHUB_TOKEN }} 22 | publish_dir: result 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | dist-* 3 | cabal-dev 4 | *.o 5 | *.hi 6 | *.hie 7 | *.chi 8 | *.chs.h 9 | *.dyn_o 10 | *.dyn_hi 11 | .hpc 12 | .hsenv 13 | .cabal-sandbox/ 14 | cabal.sandbox.config 15 | *.prof 16 | *.aux 17 | *.hp 18 | *.eventlog 19 | .stack-work/ 20 | cabal.project.local 21 | cabal.project.local~ 22 | .HTF/ 23 | .ghc.environment.* 24 | result 25 | result-* 26 | 27 | .direnv 28 | /.pre-commit-config.yaml -------------------------------------------------------------------------------- /.hlint.yaml: -------------------------------------------------------------------------------- 1 | # Ours 2 | - ignore: {name: Use camelCase } 3 | 4 | # Relude's hlint.yaml 5 | - arguments: 6 | - "-XConstraintKinds" 7 | - "-XDeriveGeneric" 8 | - "-XGeneralizedNewtypeDeriving" 9 | - "-XLambdaCase" 10 | - "-XOverloadedStrings" 11 | - "-XRecordWildCards" 12 | - "-XScopedTypeVariables" 13 | - "-XStandaloneDeriving" 14 | - "-XTupleSections" 15 | - "-XTypeApplications" 16 | - "-XViewPatterns" 17 | - ignore: 18 | name: Use head 19 | - ignore: 20 | name: Use Foldable.forM_ 21 | - hint: 22 | lhs: "pure ()" 23 | note: "Use 'pass'" 24 | rhs: pass 25 | - hint: 26 | lhs: "return ()" 27 | note: "Use 'pass'" 28 | rhs: pass 29 | - hint: 30 | lhs: "(: [])" 31 | note: "Use `one`" 32 | rhs: one 33 | - hint: 34 | lhs: "(:| [])" 35 | note: "Use `one`" 36 | rhs: one 37 | - hint: 38 | lhs: Data.Sequence.singleton 39 | note: "Use `one`" 40 | rhs: one 41 | - hint: 42 | lhs: Data.Text.singleton 43 | note: "Use `one`" 44 | rhs: one 45 | - hint: 46 | lhs: Data.Text.Lazy.singleton 47 | note: "Use `one`" 48 | rhs: one 49 | - hint: 50 | lhs: Data.ByteString.singleton 51 | note: "Use `one`" 52 | rhs: one 53 | - hint: 54 | lhs: Data.ByteString.Lazy.singleton 55 | note: "Use `one`" 56 | rhs: one 57 | - hint: 58 | lhs: Data.Map.singleton 59 | note: "Use `one`" 60 | rhs: one 61 | - hint: 62 | lhs: Data.Map.Strict.singleton 63 | note: "Use `one`" 64 | rhs: one 65 | - hint: 66 | lhs: Data.HashMap.Strict.singleton 67 | note: "Use `one`" 68 | rhs: one 69 | - hint: 70 | lhs: Data.HashMap.Lazy.singleton 71 | note: "Use `one`" 72 | rhs: one 73 | - hint: 74 | lhs: Data.IntMap.singleton 75 | note: "Use `one`" 76 | rhs: one 77 | - hint: 78 | lhs: Data.IntMap.Strict.singleton 79 | note: "Use `one`" 80 | rhs: one 81 | - hint: 82 | lhs: Data.Set.singleton 83 | note: "Use `one`" 84 | rhs: one 85 | - hint: 86 | lhs: Data.HashSet.singleton 87 | note: "Use `one`" 88 | rhs: one 89 | - hint: 90 | lhs: Data.IntSet.singleton 91 | note: "Use `one`" 92 | rhs: one 93 | - warn: 94 | lhs: Control.Exception.evaluate 95 | rhs: evaluateWHNF 96 | - warn: 97 | lhs: "Control.Exception.evaluate (force x)" 98 | rhs: evaluateNF x 99 | - warn: 100 | lhs: "Control.Exception.evaluate (x `deepseq` ())" 101 | rhs: evaluateNF_ x 102 | - warn: 103 | lhs: "void (evaluateWHNF x)" 104 | rhs: evaluateWHNF_ x 105 | - warn: 106 | lhs: "void (evaluateNF x)" 107 | rhs: evaluateNF_ x 108 | - hint: 109 | lhs: Control.Exception.throw 110 | note: "Use 'impureThrow'" 111 | rhs: impureThrow 112 | - warn: 113 | lhs: Data.Text.IO.readFile 114 | rhs: readFileText 115 | - warn: 116 | lhs: Data.Text.IO.writeFile 117 | rhs: writeFileText 118 | - warn: 119 | lhs: Data.Text.IO.appendFile 120 | rhs: appendFileText 121 | - warn: 122 | lhs: Data.Text.Lazy.IO.readFile 123 | rhs: readFileLText 124 | - warn: 125 | lhs: Data.Text.Lazy.IO.writeFile 126 | rhs: writeFileLText 127 | - warn: 128 | lhs: Data.Text.Lazy.IO.appendFile 129 | rhs: appendFileLText 130 | - warn: 131 | lhs: Data.ByteString.readFile 132 | rhs: readFileBS 133 | - warn: 134 | lhs: Data.ByteString.writeFile 135 | rhs: writeFileBS 136 | - warn: 137 | lhs: Data.ByteString.appendFile 138 | rhs: appendFileBS 139 | - warn: 140 | lhs: Data.ByteString.Lazy.readFile 141 | rhs: readFileLBS 142 | - warn: 143 | lhs: Data.ByteString.Lazy.writeFile 144 | rhs: writeFileLBS 145 | - warn: 146 | lhs: Data.ByteString.Lazy.appendFile 147 | rhs: appendFileLBS 148 | - hint: 149 | lhs: "foldl' (flip f)" 150 | note: "Use 'flipfoldl''" 151 | rhs: "flipfoldl' f" 152 | - warn: 153 | lhs: "foldl' (+) 0" 154 | rhs: sum 155 | - warn: 156 | lhs: "foldl' (*) 1" 157 | rhs: product 158 | - hint: 159 | lhs: "fmap and (sequence s)" 160 | note: Applying this hint would mean that some actions that were being executed previously would no longer be executed. 161 | rhs: andM s 162 | - hint: 163 | lhs: "and <$> sequence s" 164 | note: Applying this hint would mean that some actions that were being executed previously would no longer be executed. 165 | rhs: andM s 166 | - hint: 167 | lhs: "fmap or (sequence s)" 168 | note: Applying this hint would mean that some actions that were being executed previously would no longer be executed. 169 | rhs: orM s 170 | - hint: 171 | lhs: "or <$> sequence s" 172 | note: Applying this hint would mean that some actions that were being executed previously would no longer be executed. 173 | rhs: orM s 174 | - hint: 175 | lhs: "fmap and (mapM f s)" 176 | note: Applying this hint would mean that some actions that were being executed previously would no longer be executed. 177 | rhs: allM f s 178 | - hint: 179 | lhs: "and <$> mapM f s" 180 | note: Applying this hint would mean that some actions that were being executed previously would no longer be executed. 181 | rhs: allM f s 182 | - hint: 183 | lhs: "fmap or (mapM f s)" 184 | note: Applying this hint would mean that some actions that were being executed previously would no longer be executed. 185 | rhs: anyM f s 186 | - hint: 187 | lhs: "or <$> mapM f s" 188 | note: Applying this hint would mean that some actions that were being executed previously would no longer be executed. 189 | rhs: anyM f s 190 | - warn: 191 | lhs: "getAlt (foldMap (Alt . f) xs)" 192 | rhs: asumMap xs 193 | - warn: 194 | lhs: "getAlt . foldMap (Alt . f)" 195 | rhs: asumMap 196 | - hint: 197 | lhs: "foldr (\\x acc -> f x <|> acc) empty" 198 | note: "Use 'asumMap'" 199 | rhs: asumMap f 200 | - hint: 201 | lhs: "asum (map f xs)" 202 | note: "Use 'asumMap'" 203 | rhs: asumMap f xs 204 | - warn: 205 | lhs: "map fst &&& map snd" 206 | rhs: unzip 207 | - hint: 208 | lhs: "fmap (fmap f) x" 209 | note: "Use '(<<$>>)'" 210 | rhs: "f <<$>> x" 211 | - hint: 212 | lhs: "(\\f -> f x) <$> ff" 213 | note: Use flap operator 214 | rhs: "ff ?? x" 215 | - hint: 216 | lhs: "fmap (\\f -> f x) ff" 217 | note: Use flap operator 218 | rhs: "ff ?? x" 219 | - hint: 220 | lhs: "fmap ($ x) ff" 221 | note: Use flap operator 222 | rhs: "ff ?? x" 223 | - hint: 224 | lhs: "($ x) <$> ff" 225 | note: Use flap operator 226 | rhs: "ff ?? x" 227 | - warn: 228 | lhs: "fmap f (nonEmpty x)" 229 | rhs: viaNonEmpty f x 230 | - warn: 231 | lhs: fmap f . nonEmpty 232 | rhs: viaNonEmpty f 233 | - warn: 234 | lhs: "f <$> nonEmpty x" 235 | rhs: viaNonEmpty f x 236 | - warn: 237 | lhs: partitionEithers . map f 238 | rhs: partitionWith f 239 | - warn: 240 | lhs: partitionEithers $ map f x 241 | rhs: partitionWith f x 242 | - warn: 243 | lhs: "f >>= guard" 244 | rhs: guardM f 245 | - warn: 246 | lhs: guard =<< f 247 | rhs: guardM f 248 | - warn: 249 | lhs: forever 250 | note: "'forever' is loosely typed and may hide errors" 251 | rhs: infinitely 252 | - warn: 253 | lhs: "whenM (not <$> x)" 254 | rhs: unlessM x 255 | - warn: 256 | lhs: "unlessM (not <$> x)" 257 | rhs: whenM x 258 | - warn: 259 | lhs: "either (const True) (const False)" 260 | rhs: isLeft 261 | - warn: 262 | lhs: "either (const False) (const True)" 263 | rhs: isRight 264 | - warn: 265 | lhs: "either id (const a)" 266 | rhs: fromLeft a 267 | - warn: 268 | lhs: "either (const b) id" 269 | rhs: fromRight b 270 | - warn: 271 | lhs: "either Just (const Nothing)" 272 | rhs: leftToMaybe 273 | - warn: 274 | lhs: "either (const Nothing) Just" 275 | rhs: rightToMaybe 276 | - warn: 277 | lhs: "maybe (Left l) Right" 278 | rhs: maybeToRight l 279 | - warn: 280 | lhs: "maybe (Right r) Left" 281 | rhs: maybeToLeft r 282 | - warn: 283 | lhs: "case m of Just x -> f x; Nothing -> pure ()" 284 | rhs: whenJust m f 285 | - warn: 286 | lhs: "case m of Just x -> f x; Nothing -> return ()" 287 | rhs: whenJust m f 288 | - warn: 289 | lhs: "case m of Just x -> f x; Nothing -> pass" 290 | rhs: whenJust m f 291 | - warn: 292 | lhs: "case m of Nothing -> pure () ; Just x -> f x" 293 | rhs: whenJust m f 294 | - warn: 295 | lhs: "case m of Nothing -> return (); Just x -> f x" 296 | rhs: whenJust m f 297 | - warn: 298 | lhs: "case m of Nothing -> pass ; Just x -> f x" 299 | rhs: whenJust m f 300 | - warn: 301 | lhs: "maybe (pure ()) f m" 302 | rhs: whenJust m f 303 | - warn: 304 | lhs: "maybe (return ()) f m" 305 | rhs: whenJust m f 306 | - warn: 307 | lhs: maybe pass f m 308 | rhs: whenJust m f 309 | - warn: 310 | lhs: "m >>= \\a -> whenJust a f" 311 | rhs: whenJustM m f 312 | - warn: 313 | lhs: "m >>= \\case Just x -> f x; Nothing -> pure ()" 314 | rhs: whenJustM m f 315 | - warn: 316 | lhs: "m >>= \\case Just x -> f x; Nothing -> return ()" 317 | rhs: whenJustM m f 318 | - warn: 319 | lhs: "m >>= \\case Just x -> f x; Nothing -> pass" 320 | rhs: whenJustM m f 321 | - warn: 322 | lhs: "m >>= \\case Nothing -> pure () ; Just x -> f x" 323 | rhs: whenJustM m f 324 | - warn: 325 | lhs: "m >>= \\case Nothing -> return (); Just x -> f x" 326 | rhs: whenJustM m f 327 | - warn: 328 | lhs: "m >>= \\case Nothing -> pass ; Just x -> f x" 329 | rhs: whenJustM m f 330 | - warn: 331 | lhs: "maybe (pure ()) f =<< m" 332 | rhs: whenJustM m f 333 | - warn: 334 | lhs: "maybe (return ()) f =<< m" 335 | rhs: whenJustM m f 336 | - warn: 337 | lhs: maybe pass f =<< m 338 | rhs: whenJustM m f 339 | - warn: 340 | lhs: "m >>= maybe (pure ()) f" 341 | rhs: whenJustM m f 342 | - warn: 343 | lhs: "m >>= maybe (return ()) f" 344 | rhs: whenJustM m f 345 | - warn: 346 | lhs: "m >>= maybe pass f" 347 | rhs: whenJustM m f 348 | - warn: 349 | lhs: "case m of Just _ -> pure () ; Nothing -> x" 350 | rhs: whenNothing_ m x 351 | - warn: 352 | lhs: "case m of Just _ -> return (); Nothing -> x" 353 | rhs: whenNothing_ m x 354 | - warn: 355 | lhs: "case m of Just _ -> pass ; Nothing -> x" 356 | rhs: whenNothing_ m x 357 | - warn: 358 | lhs: "case m of Nothing -> x; Just _ -> pure ()" 359 | rhs: whenNothing_ m x 360 | - warn: 361 | lhs: "case m of Nothing -> x; Just _ -> return ()" 362 | rhs: whenNothing_ m x 363 | - warn: 364 | lhs: "case m of Nothing -> x; Just _ -> pass" 365 | rhs: whenNothing_ m x 366 | - warn: 367 | lhs: "maybe x (\\_ -> pure () ) m" 368 | rhs: whenNothing_ m x 369 | - warn: 370 | lhs: "maybe x (\\_ -> return () ) m" 371 | rhs: whenNothing_ m x 372 | - warn: 373 | lhs: "maybe x (\\_ -> pass ) m" 374 | rhs: whenNothing_ m x 375 | - warn: 376 | lhs: "maybe x (const (pure () )) m" 377 | rhs: whenNothing_ m x 378 | - warn: 379 | lhs: "maybe x (const (return ())) m" 380 | rhs: whenNothing_ m x 381 | - warn: 382 | lhs: "maybe x (const pass) m" 383 | rhs: whenNothing_ m x 384 | - warn: 385 | lhs: "m >>= \\a -> whenNothing_ a x" 386 | rhs: whenNothingM_ m x 387 | - warn: 388 | lhs: "m >>= \\case Just _ -> pure () ; Nothing -> x" 389 | rhs: whenNothingM_ m x 390 | - warn: 391 | lhs: "m >>= \\case Just _ -> return (); Nothing -> x" 392 | rhs: whenNothingM_ m x 393 | - warn: 394 | lhs: "m >>= \\case Just _ -> pass ; Nothing -> x" 395 | rhs: whenNothingM_ m x 396 | - warn: 397 | lhs: "m >>= \\case Nothing -> x; Just _ -> pure ()" 398 | rhs: whenNothingM_ m x 399 | - warn: 400 | lhs: "m >>= \\case Nothing -> x; Just _ -> return ()" 401 | rhs: whenNothingM_ m x 402 | - warn: 403 | lhs: "m >>= \\case Nothing -> x; Just _ -> pass" 404 | rhs: whenNothingM_ m x 405 | - warn: 406 | lhs: "maybe x (\\_ -> pure () ) =<< m" 407 | rhs: whenNothingM_ m x 408 | - warn: 409 | lhs: "maybe x (\\_ -> return () ) =<< m" 410 | rhs: whenNothingM_ m x 411 | - warn: 412 | lhs: "maybe x (\\_ -> pass ) =<< m" 413 | rhs: whenNothingM_ m x 414 | - warn: 415 | lhs: "maybe x (const (pure () )) =<< m" 416 | rhs: whenNothingM_ m x 417 | - warn: 418 | lhs: "maybe x (const (return ())) =<< m" 419 | rhs: whenNothingM_ m x 420 | - warn: 421 | lhs: "maybe x (const pass) =<< m" 422 | rhs: whenNothingM_ m x 423 | - warn: 424 | lhs: "m >>= maybe x (\\_ -> pure ())" 425 | rhs: whenNothingM_ m x 426 | - warn: 427 | lhs: "m >>= maybe x (\\_ -> return ())" 428 | rhs: whenNothingM_ m x 429 | - warn: 430 | lhs: "m >>= maybe x (\\_ -> pass)" 431 | rhs: whenNothingM_ m x 432 | - warn: 433 | lhs: "m >>= maybe x (const (pure ()) )" 434 | rhs: whenNothingM_ m x 435 | - warn: 436 | lhs: "m >>= maybe x (const (return ()))" 437 | rhs: whenNothingM_ m x 438 | - warn: 439 | lhs: "m >>= maybe x (const pass)" 440 | rhs: whenNothingM_ m x 441 | - warn: 442 | lhs: "whenLeft ()" 443 | rhs: whenLeft_ 444 | - warn: 445 | lhs: "case m of Left x -> f x; Right _ -> pure ()" 446 | rhs: whenLeft_ m f 447 | - warn: 448 | lhs: "case m of Left x -> f x; Right _ -> return ()" 449 | rhs: whenLeft_ m f 450 | - warn: 451 | lhs: "case m of Left x -> f x; Right _ -> pass" 452 | rhs: whenLeft_ m f 453 | - warn: 454 | lhs: "case m of Right _ -> pure () ; Left x -> f x" 455 | rhs: whenLeft_ m f 456 | - warn: 457 | lhs: "case m of Right _ -> return (); Left x -> f x" 458 | rhs: whenLeft_ m f 459 | - warn: 460 | lhs: "case m of Right _ -> pass ; Left x -> f x" 461 | rhs: whenLeft_ m f 462 | - warn: 463 | lhs: "either f (\\_ -> pure () ) m" 464 | rhs: whenLeft_ m f 465 | - warn: 466 | lhs: "either f (\\_ -> return () ) m" 467 | rhs: whenLeft_ m f 468 | - warn: 469 | lhs: "either f (\\_ -> pass ) m" 470 | rhs: whenLeft_ m f 471 | - warn: 472 | lhs: "either f (const (pure () )) m" 473 | rhs: whenLeft_ m f 474 | - warn: 475 | lhs: "either f (const (return ())) m" 476 | rhs: whenLeft_ m f 477 | - warn: 478 | lhs: "either f (const pass) m" 479 | rhs: whenLeft_ m f 480 | - warn: 481 | lhs: "m >>= \\a -> whenLeft_ a f" 482 | rhs: whenLeftM_ m f 483 | - warn: 484 | lhs: "m >>= \\case Left x -> f x; Right _ -> pure ()" 485 | rhs: whenLeftM_ m f 486 | - warn: 487 | lhs: "m >>= \\case Left x -> f x; Right _ -> return ()" 488 | rhs: whenLeftM_ m f 489 | - warn: 490 | lhs: "m >>= \\case Left x -> f x; Right _ -> pass" 491 | rhs: whenLeftM_ m f 492 | - warn: 493 | lhs: "m >>= \\case Right _ -> pure () ; Left x -> f x" 494 | rhs: whenLeftM_ m f 495 | - warn: 496 | lhs: "m >>= \\case Right _ -> return (); Left x -> f x" 497 | rhs: whenLeftM_ m f 498 | - warn: 499 | lhs: "m >>= \\case Right _ -> pass ; Left x -> f x" 500 | rhs: whenLeftM_ m f 501 | - warn: 502 | lhs: "either f (\\_ -> pure () ) =<< m" 503 | rhs: whenLeftM_ m f 504 | - warn: 505 | lhs: "either f (\\_ -> return () ) =<< m" 506 | rhs: whenLeftM_ m f 507 | - warn: 508 | lhs: "either f (\\_ -> pass ) =<< m" 509 | rhs: whenLeftM_ m f 510 | - warn: 511 | lhs: "either f (const (pure () )) =<< m" 512 | rhs: whenLeftM_ m f 513 | - warn: 514 | lhs: "either f (const (return ())) =<< m" 515 | rhs: whenLeftM_ m f 516 | - warn: 517 | lhs: "either f (const pass) =<< m" 518 | rhs: whenLeftM_ m f 519 | - warn: 520 | lhs: "m >>= either f (\\_ -> pure ())" 521 | rhs: whenLeftM_ m f 522 | - warn: 523 | lhs: "m >>= either f (\\_ -> return ())" 524 | rhs: whenLeftM_ m f 525 | - warn: 526 | lhs: "m >>= either f (\\_ -> pass)" 527 | rhs: whenLeftM_ m f 528 | - warn: 529 | lhs: "m >>= either f (const (pure ()) )" 530 | rhs: whenLeftM_ m f 531 | - warn: 532 | lhs: "m >>= either f (const (return ()))" 533 | rhs: whenLeftM_ m f 534 | - warn: 535 | lhs: "m >>= either f (const pass)" 536 | rhs: whenLeftM_ m f 537 | - warn: 538 | lhs: "whenRight ()" 539 | rhs: whenRight_ 540 | - warn: 541 | lhs: "case m of Right x -> f x; Left _ -> pure ()" 542 | rhs: whenRight_ m f 543 | - warn: 544 | lhs: "case m of Right x -> f x; Left _ -> return ()" 545 | rhs: whenRight_ m f 546 | - warn: 547 | lhs: "case m of Right x -> f x; Left _ -> pass" 548 | rhs: whenRight_ m f 549 | - warn: 550 | lhs: "case m of Left _ -> pure () ; Right x -> f x" 551 | rhs: whenRight_ m f 552 | - warn: 553 | lhs: "case m of Left _ -> return (); Right x -> f x" 554 | rhs: whenRight_ m f 555 | - warn: 556 | lhs: "case m of Left _ -> pass ; Right x -> f x" 557 | rhs: whenRight_ m f 558 | - warn: 559 | lhs: "either (\\_ -> pure () ) f m" 560 | rhs: whenRight_ m f 561 | - warn: 562 | lhs: "either (\\_ -> return () ) f m" 563 | rhs: whenRight_ m f 564 | - warn: 565 | lhs: "either (\\_ -> pass ) f m" 566 | rhs: whenRight_ m f 567 | - warn: 568 | lhs: "either (const (pure () )) f m" 569 | rhs: whenRight_ m f 570 | - warn: 571 | lhs: "either (const (return ())) f m" 572 | rhs: whenRight_ m f 573 | - warn: 574 | lhs: "either (const pass) f m" 575 | rhs: whenRight_ m f 576 | - warn: 577 | lhs: "m >>= \\a -> whenRight_ a f" 578 | rhs: whenRightM_ m f 579 | - warn: 580 | lhs: "m >>= \\case Right x -> f x; Left _ -> pure () " 581 | rhs: whenRightM_ m f 582 | - warn: 583 | lhs: "m >>= \\case Right x -> f x; Left _ -> return ()" 584 | rhs: whenRightM_ m f 585 | - warn: 586 | lhs: "m >>= \\case Right x -> f x; Left _ -> pass" 587 | rhs: whenRightM_ m f 588 | - warn: 589 | lhs: "m >>= \\case Left _ -> pure () ; Right x -> f x" 590 | rhs: whenRightM_ m f 591 | - warn: 592 | lhs: "m >>= \\case Left _ -> return (); Right x -> f x" 593 | rhs: whenRightM_ m f 594 | - warn: 595 | lhs: "m >>= \\case Left _ -> pass ; Right x -> f x" 596 | rhs: whenRightM_ m f 597 | - warn: 598 | lhs: "either (\\_ -> pure () ) f =<< m" 599 | rhs: whenRightM_ m f 600 | - warn: 601 | lhs: "either (\\_ -> return () ) f =<< m" 602 | rhs: whenRightM_ m f 603 | - warn: 604 | lhs: "either (\\_ -> pass ) f =<< m" 605 | rhs: whenRightM_ m f 606 | - warn: 607 | lhs: "either (const (pure () )) f =<< m" 608 | rhs: whenRightM_ m f 609 | - warn: 610 | lhs: "either (const (return ())) f =<< m" 611 | rhs: whenRightM_ m f 612 | - warn: 613 | lhs: "either (const pass) f =<< m" 614 | rhs: whenRightM_ m f 615 | - warn: 616 | lhs: "m >>= either (\\_ -> pure ()) f" 617 | rhs: whenRightM_ m f 618 | - warn: 619 | lhs: "m >>= either (\\_ -> return ()) f" 620 | rhs: whenRightM_ m f 621 | - warn: 622 | lhs: "m >>= either (\\_ -> pass) f" 623 | rhs: whenRightM_ m f 624 | - warn: 625 | lhs: "m >>= either (const (pure ()) ) f" 626 | rhs: whenRightM_ m f 627 | - warn: 628 | lhs: "m >>= either (const (return ())) f" 629 | rhs: whenRightM_ m f 630 | - warn: 631 | lhs: "m >>= either (const pass) f" 632 | rhs: whenRightM_ m f 633 | - warn: 634 | lhs: "case m of Left x -> f x; Right _ -> pure d " 635 | rhs: whenLeft d m f 636 | - warn: 637 | lhs: "case m of Left x -> f x; Right _ -> return d" 638 | rhs: whenLeft d m f 639 | - warn: 640 | lhs: "case m of Right _ -> pure d ; Left x -> f x" 641 | rhs: whenLeft d m f 642 | - warn: 643 | lhs: "case m of Right _ -> return d; Left x -> f x" 644 | rhs: whenLeft d m f 645 | - warn: 646 | lhs: "either f (\\_ -> pure d ) m" 647 | rhs: whenLeft d m f 648 | - warn: 649 | lhs: "either f (\\_ -> return d ) m" 650 | rhs: whenLeft d m f 651 | - warn: 652 | lhs: "either f (const (pure d )) m" 653 | rhs: whenLeft d m f 654 | - warn: 655 | lhs: "either f (const (return d)) m" 656 | rhs: whenLeft d m f 657 | - warn: 658 | lhs: "m >>= \\a -> whenLeft d a f" 659 | rhs: whenLeftM d m f 660 | - warn: 661 | lhs: "m >>= \\case Left x -> f x; Right _ -> pure d" 662 | rhs: whenLeftM d m f 663 | - warn: 664 | lhs: "m >>= \\case Left x -> f x; Right _ -> return d" 665 | rhs: whenLeftM d m f 666 | - warn: 667 | lhs: "m >>= \\case Right _ -> pure d ; Left x -> f x" 668 | rhs: whenLeftM d m f 669 | - warn: 670 | lhs: "m >>= \\case Right _ -> return d; Left x -> f x" 671 | rhs: whenLeftM d m f 672 | - warn: 673 | lhs: "either f (\\_ -> pure d ) =<< m" 674 | rhs: whenLeftM d m f 675 | - warn: 676 | lhs: "either f (\\_ -> return d ) =<< m" 677 | rhs: whenLeftM d m f 678 | - warn: 679 | lhs: "either f (const (pure d )) =<< m" 680 | rhs: whenLeftM d m f 681 | - warn: 682 | lhs: "either f (const (return d)) =<< m" 683 | rhs: whenLeftM d m f 684 | - warn: 685 | lhs: "m >>= either f (\\_ -> pure d)" 686 | rhs: whenLeftM d m f 687 | - warn: 688 | lhs: "m >>= either f (\\_ -> return d)" 689 | rhs: whenLeftM d m f 690 | - warn: 691 | lhs: "m >>= either f (const (pure d))" 692 | rhs: whenLeftM d m f 693 | - warn: 694 | lhs: "m >>= either f (const (return d))" 695 | rhs: whenLeftM d m f 696 | - warn: 697 | lhs: "case m of Right x -> f x; Left _ -> pure d" 698 | rhs: whenRight d m f 699 | - warn: 700 | lhs: "case m of Right x -> f x; Left _ -> return d" 701 | rhs: whenRight d m f 702 | - warn: 703 | lhs: "case m of Left _ -> pure d ; Right x -> f x" 704 | rhs: whenRight d m f 705 | - warn: 706 | lhs: "case m of Left _ -> return d; Right x -> f x" 707 | rhs: whenRight d m f 708 | - warn: 709 | lhs: "either (\\_ -> pure d ) f m" 710 | rhs: whenRight d m f 711 | - warn: 712 | lhs: "either (\\_ -> return d ) f m" 713 | rhs: whenRight d m f 714 | - warn: 715 | lhs: "either (const (pure d )) f m" 716 | rhs: whenRight d m f 717 | - warn: 718 | lhs: "either (const (return d)) f m" 719 | rhs: whenRight d m f 720 | - warn: 721 | lhs: "m >>= \\a -> whenRight d a f" 722 | rhs: whenRightM d m f 723 | - warn: 724 | lhs: "m >>= \\case Right x -> f x; Left _ -> pure d" 725 | rhs: whenRightM d m f 726 | - warn: 727 | lhs: "m >>= \\case Right x -> f x; Left _ -> return d" 728 | rhs: whenRightM d m f 729 | - warn: 730 | lhs: "m >>= \\case Left _ -> pure d ; Right x -> f x" 731 | rhs: whenRightM d m f 732 | - warn: 733 | lhs: "m >>= \\case Left _ -> return d; Right x -> f x" 734 | rhs: whenRightM d m f 735 | - warn: 736 | lhs: "either (\\_ -> pure d ) f =<< m" 737 | rhs: whenRightM d m f 738 | - warn: 739 | lhs: "either (\\_ -> return d ) f =<< m" 740 | rhs: whenRightM d m f 741 | - warn: 742 | lhs: "either (const (pure d )) f =<< m" 743 | rhs: whenRightM d m f 744 | - warn: 745 | lhs: "either (const (return d)) f =<< m" 746 | rhs: whenRightM d m f 747 | - warn: 748 | lhs: "m >>= either (\\_ -> pure d) f" 749 | rhs: whenRightM d m f 750 | - warn: 751 | lhs: "m >>= either (\\_ -> return d) f" 752 | rhs: whenRightM d m f 753 | - warn: 754 | lhs: "m >>= either (const (pure d) ) f" 755 | rhs: whenRightM d m f 756 | - warn: 757 | lhs: "m >>= either (const (return d)) f" 758 | rhs: whenRightM d m f 759 | - warn: 760 | lhs: "case m of [] -> return (); (x:xs) -> f (x :| xs)" 761 | rhs: whenNotNull m f 762 | - warn: 763 | lhs: "case m of [] -> pure () ; (x:xs) -> f (x :| xs)" 764 | rhs: whenNotNull m f 765 | - warn: 766 | lhs: "case m of [] -> pass ; (x:xs) -> f (x :| xs)" 767 | rhs: whenNotNull m f 768 | - warn: 769 | lhs: "case m of (x:xs) -> f (x :| xs); [] -> return ()" 770 | rhs: whenNotNull m f 771 | - warn: 772 | lhs: "case m of (x:xs) -> f (x :| xs); [] -> pure () " 773 | rhs: whenNotNull m f 774 | - warn: 775 | lhs: "case m of (x:xs) -> f (x :| xs); [] -> pass " 776 | rhs: whenNotNull m f 777 | - warn: 778 | lhs: "m >>= \\case [] -> pass ; (x:xs) -> f (x :| xs)" 779 | rhs: whenNotNullM m f 780 | - warn: 781 | lhs: "m >>= \\case [] -> pure () ; (x:xs) -> f (x :| xs)" 782 | rhs: whenNotNullM m f 783 | - warn: 784 | lhs: "m >>= \\case [] -> return (); (x:xs) -> f (x :| xs)" 785 | rhs: whenNotNullM m f 786 | - warn: 787 | lhs: "m >>= \\case (x:xs) -> f (x :| xs); [] -> pass " 788 | rhs: whenNotNullM m f 789 | - warn: 790 | lhs: "m >>= \\case (x:xs) -> f (x :| xs); [] -> pure () " 791 | rhs: whenNotNullM m f 792 | - warn: 793 | lhs: "m >>= \\case (x:xs) -> f (x :| xs); [] -> return ()" 794 | rhs: whenNotNullM m f 795 | - warn: 796 | lhs: mapMaybe leftToMaybe 797 | rhs: lefts 798 | - warn: 799 | lhs: mapMaybe rightToMaybe 800 | rhs: rights 801 | - warn: 802 | lhs: flip runReaderT 803 | rhs: usingReaderT 804 | - warn: 805 | lhs: flip runReader 806 | rhs: usingReader 807 | - warn: 808 | lhs: flip runStateT 809 | rhs: usingStateT 810 | - warn: 811 | lhs: flip runState 812 | rhs: usingState 813 | - warn: 814 | lhs: "fst <$> usingStateT s st" 815 | rhs: evaluatingStateT s st 816 | - warn: 817 | lhs: "fst (usingState s st)" 818 | rhs: evaluatingState s st 819 | - warn: 820 | lhs: "snd <$> usingStateT s st" 821 | rhs: executingStateT s st 822 | - warn: 823 | lhs: "snd (usingState s st)" 824 | rhs: executingState s st 825 | - warn: 826 | lhs: "MaybeT (pure m)" 827 | rhs: hoistMaybe m 828 | - warn: 829 | lhs: "MaybeT (return m)" 830 | rhs: hoistMaybe m 831 | - warn: 832 | lhs: MaybeT . pure 833 | rhs: hoistMaybe 834 | - warn: 835 | lhs: MaybeT . return 836 | rhs: hoistMaybe 837 | - warn: 838 | lhs: "ExceptT (pure m)" 839 | rhs: hoistEither m 840 | - warn: 841 | lhs: "ExceptT (return m)" 842 | rhs: hoistEither m 843 | - warn: 844 | lhs: ExceptT . pure 845 | rhs: hoistEither 846 | - warn: 847 | lhs: ExceptT . return 848 | rhs: hoistEither 849 | - warn: 850 | lhs: fromMaybe mempty 851 | rhs: maybeToMonoid 852 | - warn: 853 | lhs: "m ?: mempty" 854 | rhs: maybeToMonoid m 855 | - warn: 856 | lhs: "Data.Map.toAscList (Data.Map.fromList x)" 857 | rhs: sortWith fst x 858 | - warn: 859 | lhs: "Data.Map.toDescList (Data.Map.fromList x)" 860 | rhs: "sortWith (Down . fst) x" 861 | - warn: 862 | lhs: "Data.Set.toList (Data.Set.fromList l)" 863 | rhs: sortNub l 864 | - warn: 865 | lhs: "Data.Set.assocs (Data.Set.fromList l)" 866 | rhs: sortNub l 867 | - warn: 868 | lhs: "Data.Set.toAscList (Data.Set.fromList l)" 869 | rhs: sortNub l 870 | - warn: 871 | lhs: "Data.HashSet.toList (Data.HashSet.fromList l)" 872 | rhs: unstableNub l 873 | - warn: 874 | lhs: nub 875 | note: "'nub' is O(n^2), 'ordNub' is O(n log n)" 876 | rhs: ordNub 877 | - warn: 878 | lhs: "sortBy (comparing f)" 879 | note: "If the function you are using for 'comparing' is slow, use 'sortOn' instead of 'sortWith', because 'sortOn' caches applications the function and 'sortWith' doesn't." 880 | rhs: sortWith f 881 | - warn: 882 | lhs: sortOn fst 883 | note: "'sortWith' will be faster here because it doesn't do caching" 884 | rhs: sortWith fst 885 | - warn: 886 | lhs: sortOn snd 887 | note: "'sortWith' will be faster here because it doesn't do caching" 888 | rhs: sortWith snd 889 | - warn: 890 | lhs: "sortOn (Down . fst)" 891 | note: "'sortWith' will be faster here because it doesn't do caching" 892 | rhs: "sortWith (Down . fst)" 893 | - warn: 894 | lhs: "sortOn (Down . snd)" 895 | note: "'sortWith' will be faster here because it doesn't do caching" 896 | rhs: "sortWith (Down . snd)" 897 | - warn: 898 | lhs: Data.Text.IO.putStr 899 | rhs: putText 900 | - warn: 901 | lhs: Data.Text.IO.putStrLn 902 | rhs: putTextLn 903 | - warn: 904 | lhs: Data.Text.Lazy.IO.putStr 905 | rhs: putLText 906 | - warn: 907 | lhs: Data.Text.Lazy.IO.putStrLn 908 | rhs: putLTextLn 909 | - warn: 910 | lhs: Data.ByteString.Char8.putStr 911 | rhs: putBS 912 | - warn: 913 | lhs: Data.ByteString.Char8.putStrLn 914 | rhs: putBSLn 915 | - warn: 916 | lhs: Data.ByteString.Lazy.Char8.putStr 917 | rhs: putLBS 918 | - warn: 919 | lhs: Data.ByteString.Lazy.Char8.putStrLn 920 | rhs: putLBSLn 921 | - warn: 922 | lhs: Data.Text.Lazy.Text 923 | rhs: LText 924 | - warn: 925 | lhs: Data.ByteString.Lazy.ByteString 926 | rhs: LByteString 927 | - warn: 928 | lhs: Data.ByteString.UTF8.fromString 929 | rhs: encodeUtf8 930 | - warn: 931 | lhs: Data.ByteString.UTF8.toString 932 | rhs: decodeUtf8 933 | - warn: 934 | lhs: Data.Text.Encoding.encodeUtf8 935 | rhs: encodeUtf8 936 | - warn: 937 | lhs: Data.Text.Encoding.decodeUtf8 938 | rhs: decodeUtf8 939 | - warn: 940 | lhs: "Data.ByteString.Lazy.toStrict (encodeUtf8 x)" 941 | rhs: encodeUtf8 x 942 | - warn: 943 | lhs: "toStrict (encodeUtf8 x)" 944 | rhs: encodeUtf8 x 945 | - warn: 946 | lhs: "decodeUtf8 (Data.ByteString.Lazy.fromStrict x)" 947 | rhs: decodeUtf8 x 948 | - warn: 949 | lhs: "decodeUtf8 (fromStrict x)" 950 | rhs: decodeUtf8 x 951 | - warn: 952 | lhs: Data.ByteString.Lazy.UTF8.fromString 953 | rhs: encodeUtf8 954 | - warn: 955 | lhs: Data.ByteString.Lazy.UTF8.toString 956 | rhs: decodeUtf8 957 | - warn: 958 | lhs: "Data.ByteString.Lazy.fromStrict (Data.Text.Encoding.encodeUtf8 x)" 959 | rhs: encodeUtf8 x 960 | - warn: 961 | lhs: "Data.ByteString.Lazy.fromStrict (encodeUtf8 x)" 962 | rhs: encodeUtf8 x 963 | - warn: 964 | lhs: "Data.Text.Encoding.decodeUtf8 (Data.ByteString.Lazy.toStrict x)" 965 | rhs: decodeUtf8 x 966 | - warn: 967 | lhs: "Data.Text.Encoding.decodeUtf8 (toStrict x)" 968 | rhs: decodeUtf8 x 969 | - warn: 970 | lhs: "decodeUtf8 (Data.ByteString.Lazy.toStrict x)" 971 | rhs: decodeUtf8 x 972 | - warn: 973 | lhs: "decodeUtf8 (toStrict x)" 974 | rhs: decodeUtf8 x 975 | - warn: 976 | lhs: Data.Text.pack 977 | rhs: toText 978 | - warn: 979 | lhs: Data.Text.unpack 980 | rhs: toString 981 | - warn: 982 | lhs: Data.Text.Lazy.pack 983 | rhs: toLText 984 | - warn: 985 | lhs: Data.Text.Lazy.unpack 986 | rhs: toString 987 | - warn: 988 | lhs: Data.Text.Lazy.toStrict 989 | rhs: toText 990 | - warn: 991 | lhs: Data.Text.Lazy.fromStrict 992 | rhs: toLText 993 | - warn: 994 | lhs: "Data.Text.pack (show x)" 995 | rhs: show x 996 | - warn: 997 | lhs: "Data.Text.Lazy.pack (show x)" 998 | rhs: show x 999 | - warn: 1000 | lhs: Data.ByteString.Lazy.fromStrict 1001 | rhs: fromStrict 1002 | - warn: 1003 | lhs: Data.ByteString.Lazy.toStrict 1004 | rhs: toStrict 1005 | - warn: 1006 | lhs: Data.Text.Lazy.fromStrict 1007 | rhs: fromStrict 1008 | - warn: 1009 | lhs: Data.Text.Lazy.toStrict 1010 | rhs: toStrict 1011 | - warn: 1012 | lhs: Control.Applicative.Alternative 1013 | name: "Use 'Alternative' from Relude" 1014 | note: "'Alternative' is already exported from Relude" 1015 | rhs: Alternative 1016 | - warn: 1017 | lhs: Control.Applicative.empty 1018 | name: "Use 'empty' from Relude" 1019 | note: "'empty' is already exported from Relude" 1020 | rhs: empty 1021 | - warn: 1022 | lhs: "(Control.Applicative.<|>)" 1023 | name: "Use '<|>' from Relude" 1024 | note: "Operator '(<|>)' is already exported from Relude" 1025 | rhs: "(<|>)" 1026 | - warn: 1027 | lhs: Control.Applicative.some 1028 | name: "Use 'some' from Relude" 1029 | note: "'some' is already exported from Relude" 1030 | rhs: some 1031 | - warn: 1032 | lhs: Control.Applicative.many 1033 | name: "Use 'many' from Relude" 1034 | note: "'many' is already exported from Relude" 1035 | rhs: many 1036 | - warn: 1037 | lhs: Control.Applicative.Const 1038 | name: "Use 'Const' from Relude" 1039 | note: "'Const' is already exported from Relude" 1040 | rhs: Const 1041 | - warn: 1042 | lhs: Control.Applicative.getConst 1043 | name: "Use 'getConst' from Relude" 1044 | note: "'getConst' is already exported from Relude" 1045 | rhs: getConst 1046 | - warn: 1047 | lhs: Control.Applicative.ZipList 1048 | name: "Use 'ZipList' from Relude" 1049 | note: "'ZipList' is already exported from Relude" 1050 | rhs: ZipList 1051 | - warn: 1052 | lhs: Control.Applicative.getZipList 1053 | name: "Use 'getZipList' from Relude" 1054 | note: "'getZipList' is already exported from Relude" 1055 | rhs: getZipList 1056 | - warn: 1057 | lhs: Control.Applicative.liftA2 1058 | name: "Use 'liftA2' from Relude" 1059 | note: "'liftA2' is already exported from Relude" 1060 | rhs: liftA2 1061 | - warn: 1062 | lhs: Control.Applicative.liftA3 1063 | name: "Use 'liftA3' from Relude" 1064 | note: "'liftA3' is already exported from Relude" 1065 | rhs: liftA3 1066 | - warn: 1067 | lhs: Control.Applicative.optional 1068 | name: "Use 'optional' from Relude" 1069 | note: "'optional' is already exported from Relude" 1070 | rhs: optional 1071 | - warn: 1072 | lhs: "(Control.Applicative.<**>)" 1073 | name: "Use '<**>' from Relude" 1074 | note: "Operator '(<**>)' is already exported from Relude" 1075 | rhs: "(<**>)" 1076 | - warn: 1077 | lhs: Data.Bits.xor 1078 | name: "Use 'xor' from Relude" 1079 | note: "'xor' is already exported from Relude" 1080 | rhs: xor 1081 | - warn: 1082 | lhs: Data.Char.chr 1083 | name: "Use 'chr' from Relude" 1084 | note: "'chr' is already exported from Relude" 1085 | rhs: chr 1086 | - warn: 1087 | lhs: Data.Int.Int8 1088 | name: "Use 'Int8' from Relude" 1089 | note: "'Int8' is already exported from Relude" 1090 | rhs: Int8 1091 | - warn: 1092 | lhs: Data.Int.Int16 1093 | name: "Use 'Int16' from Relude" 1094 | note: "'Int16' is already exported from Relude" 1095 | rhs: Int16 1096 | - warn: 1097 | lhs: Data.Int.Int32 1098 | name: "Use 'Int32' from Relude" 1099 | note: "'Int32' is already exported from Relude" 1100 | rhs: Int32 1101 | - warn: 1102 | lhs: Data.Int.Int64 1103 | name: "Use 'Int64' from Relude" 1104 | note: "'Int64' is already exported from Relude" 1105 | rhs: Int64 1106 | - warn: 1107 | lhs: Data.Word.Word8 1108 | name: "Use 'Word8' from Relude" 1109 | note: "'Word8' is already exported from Relude" 1110 | rhs: Word8 1111 | - warn: 1112 | lhs: Data.Word.Word16 1113 | name: "Use 'Word16' from Relude" 1114 | note: "'Word16' is already exported from Relude" 1115 | rhs: Word16 1116 | - warn: 1117 | lhs: Data.Word.Word32 1118 | name: "Use 'Word32' from Relude" 1119 | note: "'Word32' is already exported from Relude" 1120 | rhs: Word32 1121 | - warn: 1122 | lhs: Data.Word.Word64 1123 | name: "Use 'Word64' from Relude" 1124 | note: "'Word64' is already exported from Relude" 1125 | rhs: Word64 1126 | - warn: 1127 | lhs: Data.Word.byteSwap16 1128 | name: "Use 'byteSwap16' from Relude" 1129 | note: "'byteSwap16' is already exported from Relude" 1130 | rhs: byteSwap16 1131 | - warn: 1132 | lhs: Data.Word.byteSwap32 1133 | name: "Use 'byteSwap32' from Relude" 1134 | note: "'byteSwap32' is already exported from Relude" 1135 | rhs: byteSwap32 1136 | - warn: 1137 | lhs: Data.Word.byteSwap64 1138 | name: "Use 'byteSwap64' from Relude" 1139 | note: "'byteSwap64' is already exported from Relude" 1140 | rhs: byteSwap64 1141 | - warn: 1142 | lhs: Numeric.Natural.Natural 1143 | name: "Use 'Natural' from Relude" 1144 | note: "'Natural' is already exported from Relude" 1145 | rhs: Natural 1146 | - warn: 1147 | lhs: System.IO.IOMode 1148 | name: "Use 'IOMode' from Relude" 1149 | note: "'IOMode' is already exported from Relude" 1150 | rhs: IOMode 1151 | - warn: 1152 | lhs: System.IO.ReadMode 1153 | name: "Use 'ReadMode' from Relude" 1154 | note: "'ReadMode' is already exported from Relude" 1155 | rhs: ReadMode 1156 | - warn: 1157 | lhs: System.IO.WriteMode 1158 | name: "Use 'WriteMode' from Relude" 1159 | note: "'WriteMode' is already exported from Relude" 1160 | rhs: WriteMode 1161 | - warn: 1162 | lhs: System.IO.AppendMode 1163 | name: "Use 'AppendMode' from Relude" 1164 | note: "'AppendMode' is already exported from Relude" 1165 | rhs: AppendMode 1166 | - warn: 1167 | lhs: System.IO.ReadWriteMode 1168 | name: "Use 'ReadWriteMode' from Relude" 1169 | note: "'ReadWriteMode' is already exported from Relude" 1170 | rhs: ReadWriteMode 1171 | - warn: 1172 | lhs: Data.Ord.Down 1173 | name: "Use 'Down' from Relude" 1174 | note: "'Down' is already exported from Relude" 1175 | rhs: Down 1176 | - warn: 1177 | lhs: Data.Ord.comparing 1178 | name: "Use 'comparing' from Relude" 1179 | note: "'comparing' is already exported from Relude" 1180 | rhs: comparing 1181 | - warn: 1182 | lhs: Data.Coerce.Coercible 1183 | name: "Use 'Coercible' from Relude" 1184 | note: "'Coercible' is already exported from Relude" 1185 | rhs: Coercible 1186 | - warn: 1187 | lhs: Data.Coerce.coerce 1188 | name: "Use 'coerce' from Relude" 1189 | note: "'coerce' is already exported from Relude" 1190 | rhs: coerce 1191 | - warn: 1192 | lhs: Data.Kind.Constraint 1193 | name: "Use 'Constraint' from Relude" 1194 | note: "'Constraint' is already exported from Relude" 1195 | rhs: Constraint 1196 | - warn: 1197 | lhs: Data.Kind.Type 1198 | name: "Use 'Type' from Relude" 1199 | note: "'Type' is already exported from Relude" 1200 | rhs: Type 1201 | - warn: 1202 | lhs: Data.Typeable.Typeable 1203 | name: "Use 'Typeable' from Relude" 1204 | note: "'Typeable' is already exported from Relude" 1205 | rhs: Typeable 1206 | - warn: 1207 | lhs: Data.Proxy.Proxy 1208 | name: "Use 'Proxy' from Relude" 1209 | note: "'Proxy' is already exported from Relude" 1210 | rhs: Proxy 1211 | - warn: 1212 | lhs: Data.Typeable.Typeable 1213 | name: "Use 'Typeable' from Relude" 1214 | note: "'Typeable' is already exported from Relude" 1215 | rhs: Typeable 1216 | - warn: 1217 | lhs: Data.Void.Void 1218 | name: "Use 'Void' from Relude" 1219 | note: "'Void' is already exported from Relude" 1220 | rhs: Void 1221 | - warn: 1222 | lhs: Data.Void.absurd 1223 | name: "Use 'absurd' from Relude" 1224 | note: "'absurd' is already exported from Relude" 1225 | rhs: absurd 1226 | - warn: 1227 | lhs: Data.Void.vacuous 1228 | name: "Use 'vacuous' from Relude" 1229 | note: "'vacuous' is already exported from Relude" 1230 | rhs: vacuous 1231 | - warn: 1232 | lhs: Data.Base.maxInt 1233 | name: "Use 'maxInt' from Relude" 1234 | note: "'maxInt' is already exported from Relude" 1235 | rhs: maxInt 1236 | - warn: 1237 | lhs: Data.Base.minInt 1238 | name: "Use 'minInt' from Relude" 1239 | note: "'minInt' is already exported from Relude" 1240 | rhs: minInt 1241 | - warn: 1242 | lhs: Data.Base.ord 1243 | name: "Use 'ord' from Relude" 1244 | note: "'ord' is already exported from Relude" 1245 | rhs: ord 1246 | - warn: 1247 | lhs: GHC.Enum.boundedEnumFrom 1248 | name: "Use 'boundedEnumFrom' from Relude" 1249 | note: "'boundedEnumFrom' is already exported from Relude" 1250 | rhs: boundedEnumFrom 1251 | - warn: 1252 | lhs: GHC.Enum.boundedEnumFromThen 1253 | name: "Use 'boundedEnumFromThen' from Relude" 1254 | note: "'boundedEnumFromThen' is already exported from Relude" 1255 | rhs: boundedEnumFromThen 1256 | - warn: 1257 | lhs: GHC.Generics.Generic 1258 | name: "Use 'Generic' from Relude" 1259 | note: "'Generic' is already exported from Relude" 1260 | rhs: Generic 1261 | - warn: 1262 | lhs: GHC.Real.Ratio 1263 | name: "Use 'Ratio' from Relude" 1264 | note: "'Ratio' is already exported from Relude" 1265 | rhs: Ratio 1266 | - warn: 1267 | lhs: GHC.Real.Rational 1268 | name: "Use 'Rational' from Relude" 1269 | note: "'Rational' is already exported from Relude" 1270 | rhs: Rational 1271 | - warn: 1272 | lhs: GHC.Real.denominator 1273 | name: "Use 'denominator' from Relude" 1274 | note: "'denominator' is already exported from Relude" 1275 | rhs: denominator 1276 | - warn: 1277 | lhs: GHC.Real.numerator 1278 | name: "Use 'numerator' from Relude" 1279 | note: "'numerator' is already exported from Relude" 1280 | rhs: numerator 1281 | - warn: 1282 | lhs: GHC.TypeNats.CmpNat 1283 | name: "Use 'CmpNat' from Relude" 1284 | note: "'CmpNat' is already exported from Relude" 1285 | rhs: CmpNat 1286 | - warn: 1287 | lhs: GHC.TypeNats.KnownNat 1288 | name: "Use 'KnownNat' from Relude" 1289 | note: "'KnownNat' is already exported from Relude" 1290 | rhs: KnownNat 1291 | - warn: 1292 | lhs: GHC.TypeNats.Nat 1293 | name: "Use 'Nat' from Relude" 1294 | note: "'Nat' is already exported from Relude" 1295 | rhs: Nat 1296 | - warn: 1297 | lhs: GHC.TypeNats.SomeNat 1298 | name: "Use 'SomeNat' from Relude" 1299 | note: "'SomeNat' is already exported from Relude" 1300 | rhs: SomeNat 1301 | - warn: 1302 | lhs: GHC.TypeNats.natVal 1303 | name: "Use 'natVal' from Relude" 1304 | note: "'natVal' is already exported from Relude" 1305 | rhs: natVal 1306 | - warn: 1307 | lhs: GHC.TypeNats.someNatVal 1308 | name: "Use 'someNatVal' from Relude" 1309 | note: "'someNatVal' is already exported from Relude" 1310 | rhs: someNatVal 1311 | - warn: 1312 | lhs: GHC.TypeLits.CmpNat 1313 | name: "Use 'CmpNat' from Relude" 1314 | note: "'CmpNat' is already exported from Relude" 1315 | rhs: CmpNat 1316 | - warn: 1317 | lhs: GHC.TypeLits.KnownNat 1318 | name: "Use 'KnownNat' from Relude" 1319 | note: "'KnownNat' is already exported from Relude" 1320 | rhs: KnownNat 1321 | - warn: 1322 | lhs: GHC.TypeLits.Nat 1323 | name: "Use 'Nat' from Relude" 1324 | note: "'Nat' is already exported from Relude" 1325 | rhs: Nat 1326 | - warn: 1327 | lhs: GHC.TypeLits.SomeNat 1328 | name: "Use 'SomeNat' from Relude" 1329 | note: "'SomeNat' is already exported from Relude" 1330 | rhs: SomeNat 1331 | - warn: 1332 | lhs: GHC.TypeLits.natVal 1333 | name: "Use 'natVal' from Relude" 1334 | note: "'natVal' is already exported from Relude" 1335 | rhs: natVal 1336 | - warn: 1337 | lhs: GHC.TypeLits.someNatVal 1338 | name: "Use 'someNatVal' from Relude" 1339 | note: "'someNatVal' is already exported from Relude" 1340 | rhs: someNatVal 1341 | - warn: 1342 | lhs: GHC.ExecutionStack.getStackTrace 1343 | name: "Use 'getStackTrace' from Relude" 1344 | note: "'getStackTrace' is already exported from Relude" 1345 | rhs: getStackTrace 1346 | - warn: 1347 | lhs: GHC.ExecutionStack.showStackTrace 1348 | name: "Use 'showStackTrace' from Relude" 1349 | note: "'showStackTrace' is already exported from Relude" 1350 | rhs: showStackTrace 1351 | - warn: 1352 | lhs: GHC.OverloadedLabels.IsLabel 1353 | name: "Use 'IsLabel' from Relude" 1354 | note: "'IsLabel' is already exported from Relude" 1355 | rhs: IsLabel 1356 | - warn: 1357 | lhs: GHC.OverloadedLabels.fromLabel 1358 | name: "Use 'fromLabel' from Relude" 1359 | note: "'fromLabel' is already exported from Relude" 1360 | rhs: fromLabel 1361 | - warn: 1362 | lhs: GHC.Stack.CallStack 1363 | name: "Use 'CallStack' from Relude" 1364 | note: "'CallStack' is already exported from Relude" 1365 | rhs: CallStack 1366 | - warn: 1367 | lhs: GHC.Stack.HasCallStack 1368 | name: "Use 'HasCallStack' from Relude" 1369 | note: "'HasCallStack' is already exported from Relude" 1370 | rhs: HasCallStack 1371 | - warn: 1372 | lhs: GHC.Stack.callStack 1373 | name: "Use 'callStack' from Relude" 1374 | note: "'callStack' is already exported from Relude" 1375 | rhs: callStack 1376 | - warn: 1377 | lhs: GHC.Stack.currentCallStack 1378 | name: "Use 'currentCallStack' from Relude" 1379 | note: "'currentCallStack' is already exported from Relude" 1380 | rhs: currentCallStack 1381 | - warn: 1382 | lhs: GHC.Stack.getCallStack 1383 | name: "Use 'getCallStack' from Relude" 1384 | note: "'getCallStack' is already exported from Relude" 1385 | rhs: getCallStack 1386 | - warn: 1387 | lhs: GHC.Stack.prettyCallStack 1388 | name: "Use 'prettyCallStack' from Relude" 1389 | note: "'prettyCallStack' is already exported from Relude" 1390 | rhs: prettyCallStack 1391 | - warn: 1392 | lhs: GHC.Stack.prettySrcLoc 1393 | name: "Use 'prettySrcLoc' from Relude" 1394 | note: "'prettySrcLoc' is already exported from Relude" 1395 | rhs: prettySrcLoc 1396 | - warn: 1397 | lhs: GHC.Stack.withFrozenCallStack 1398 | name: "Use 'withFrozenCallStack' from Relude" 1399 | note: "'withFrozenCallStack' is already exported from Relude" 1400 | rhs: withFrozenCallStack 1401 | - warn: 1402 | lhs: Data.Bifoldable.Bifoldable 1403 | name: "Use 'Bifoldable' from Relude" 1404 | note: "'Bifoldable' is already exported from Relude" 1405 | rhs: Bifoldable 1406 | - warn: 1407 | lhs: Data.Bifoldable.bifold 1408 | name: "Use 'bifold' from Relude" 1409 | note: "'bifold' is already exported from Relude" 1410 | rhs: bifold 1411 | - warn: 1412 | lhs: Data.Bifoldable.bifoldMap 1413 | name: "Use 'bifoldMap' from Relude" 1414 | note: "'bifoldMap' is already exported from Relude" 1415 | rhs: bifoldMap 1416 | - warn: 1417 | lhs: Data.Bifoldable.bifoldr 1418 | name: "Use 'bifoldr' from Relude" 1419 | note: "'bifoldr' is already exported from Relude" 1420 | rhs: bifoldr 1421 | - warn: 1422 | lhs: Data.Bifoldable.bifoldl 1423 | name: "Use 'bifoldl' from Relude" 1424 | note: "'bifoldl' is already exported from Relude" 1425 | rhs: bifoldl 1426 | - warn: 1427 | lhs: "Data.Bifoldable.bifoldl'" 1428 | name: "Use 'bifoldl'' from Relude" 1429 | note: "'bifoldl'' is already exported from Relude" 1430 | rhs: "bifoldl'" 1431 | - warn: 1432 | lhs: Data.Bifoldable.bifoldlM 1433 | name: "Use 'bifoldlM' from Relude" 1434 | note: "'bifoldlM' is already exported from Relude" 1435 | rhs: bifoldlM 1436 | - warn: 1437 | lhs: "Data.Bifoldable.bifoldr'" 1438 | name: "Use 'bifoldr'' from Relude" 1439 | note: "'bifoldr'' is already exported from Relude" 1440 | rhs: "bifoldr'" 1441 | - warn: 1442 | lhs: Data.Bifoldable.bifoldrM 1443 | name: "Use 'bifoldrM' from Relude" 1444 | note: "'bifoldrM' is already exported from Relude" 1445 | rhs: bifoldrM 1446 | - warn: 1447 | lhs: Data.Bifoldable.bitraverse_ 1448 | name: "Use 'bitraverse_' from Relude" 1449 | note: "'bitraverse_' is already exported from Relude" 1450 | rhs: bitraverse_ 1451 | - warn: 1452 | lhs: Data.Bifoldable.bifor_ 1453 | name: "Use 'bifor_' from Relude" 1454 | note: "'bifor_' is already exported from Relude" 1455 | rhs: bifor_ 1456 | - warn: 1457 | lhs: Data.Bifoldable.biasum 1458 | name: "Use 'biasum' from Relude" 1459 | note: "'biasum' is already exported from Relude" 1460 | rhs: biasum 1461 | - warn: 1462 | lhs: Data.Bifoldable.bisequence_ 1463 | name: "Use 'bisequence_' from Relude" 1464 | note: "'bisequence_' is already exported from Relude" 1465 | rhs: bisequence_ 1466 | - warn: 1467 | lhs: Data.Bifoldable.biList 1468 | name: "Use 'biList' from Relude" 1469 | note: "'biList' is already exported from Relude" 1470 | rhs: biList 1471 | - warn: 1472 | lhs: Data.Bifoldable.binull 1473 | name: "Use 'binull' from Relude" 1474 | note: "'binull' is already exported from Relude" 1475 | rhs: binull 1476 | - warn: 1477 | lhs: Data.Bifoldable.bilength 1478 | name: "Use 'bilength' from Relude" 1479 | note: "'bilength' is already exported from Relude" 1480 | rhs: bilength 1481 | - warn: 1482 | lhs: Data.Bifoldable.bielem 1483 | name: "Use 'bielem' from Relude" 1484 | note: "'bielem' is already exported from Relude" 1485 | rhs: bielem 1486 | - warn: 1487 | lhs: Data.Bifoldable.biand 1488 | name: "Use 'biand' from Relude" 1489 | note: "'biand' is already exported from Relude" 1490 | rhs: biand 1491 | - warn: 1492 | lhs: Data.Bifoldable.bior 1493 | name: "Use 'bior' from Relude" 1494 | note: "'bior' is already exported from Relude" 1495 | rhs: bior 1496 | - warn: 1497 | lhs: Data.Bifoldable.biany 1498 | name: "Use 'biany' from Relude" 1499 | note: "'biany' is already exported from Relude" 1500 | rhs: biany 1501 | - warn: 1502 | lhs: Data.Bifoldable.biall 1503 | name: "Use 'biall' from Relude" 1504 | note: "'biall' is already exported from Relude" 1505 | rhs: biall 1506 | - warn: 1507 | lhs: Data.Bifoldable.bifind 1508 | name: "Use 'bifind' from Relude" 1509 | note: "'bifind' is already exported from Relude" 1510 | rhs: bifind 1511 | - warn: 1512 | lhs: Data.Bitraversable.Bitraversable 1513 | name: "Use 'Bitraversable' from Relude" 1514 | note: "'Bitraversable' is already exported from Relude" 1515 | rhs: Bitraversable 1516 | - warn: 1517 | lhs: Data.Bitraversable.bitraverse 1518 | name: "Use 'bitraverse' from Relude" 1519 | note: "'bitraverse' is already exported from Relude" 1520 | rhs: bitraverse 1521 | - warn: 1522 | lhs: Data.Bitraversable.bisequence 1523 | name: "Use 'bisequence' from Relude" 1524 | note: "'bisequence' is already exported from Relude" 1525 | rhs: bisequence 1526 | - warn: 1527 | lhs: Data.Bitraversable.bifor 1528 | name: "Use 'bifor' from Relude" 1529 | note: "'bifor' is already exported from Relude" 1530 | rhs: bifor 1531 | - warn: 1532 | lhs: Data.Bitraversable.bimapDefault 1533 | name: "Use 'bimapDefault' from Relude" 1534 | note: "'bimapDefault' is already exported from Relude" 1535 | rhs: bimapDefault 1536 | - warn: 1537 | lhs: Data.Bitraversable.bifoldMapDefault 1538 | name: "Use 'bifoldMapDefault' from Relude" 1539 | note: "'bifoldMapDefault' is already exported from Relude" 1540 | rhs: bifoldMapDefault 1541 | - warn: 1542 | lhs: Control.Monad.guard 1543 | name: "Use 'guard' from Relude" 1544 | note: "'guard' is already exported from Relude" 1545 | rhs: guard 1546 | - warn: 1547 | lhs: Control.Monad.unless 1548 | name: "Use 'unless' from Relude" 1549 | note: "'unless' is already exported from Relude" 1550 | rhs: unless 1551 | - warn: 1552 | lhs: Control.Monad.when 1553 | name: "Use 'when' from Relude" 1554 | note: "'when' is already exported from Relude" 1555 | rhs: when 1556 | - warn: 1557 | lhs: Data.Bool.bool 1558 | name: "Use 'bool' from Relude" 1559 | note: "'bool' is already exported from Relude" 1560 | rhs: bool 1561 | - warn: 1562 | lhs: Data.Hashable.Hashable 1563 | name: "Use 'Hashable' from Relude" 1564 | note: "'Hashable' is already exported from Relude" 1565 | rhs: Hashable 1566 | - warn: 1567 | lhs: Data.Hashable.hashWithSalt 1568 | name: "Use 'hashWithSalt' from Relude" 1569 | note: "'hashWithSalt' is already exported from Relude" 1570 | rhs: hashWithSalt 1571 | - warn: 1572 | lhs: Data.HashMap.Strict.HashMap 1573 | name: "Use 'HashMap' from Relude" 1574 | note: "'HashMap' is already exported from Relude" 1575 | rhs: HashMap 1576 | - warn: 1577 | lhs: Data.HashSet.HashSet 1578 | name: "Use 'HashSet' from Relude" 1579 | note: "'HashSet' is already exported from Relude" 1580 | rhs: HashSet 1581 | - warn: 1582 | lhs: Data.IntMap.Strict.IntMap 1583 | name: "Use 'IntMap' from Relude" 1584 | note: "'IntMap' is already exported from Relude" 1585 | rhs: IntMap 1586 | - warn: 1587 | lhs: Data.IntSet.IntSet 1588 | name: "Use 'IntSet' from Relude" 1589 | note: "'IntSet' is already exported from Relude" 1590 | rhs: IntSet 1591 | - warn: 1592 | lhs: Data.Map.Strict.Map 1593 | name: "Use 'Map' from Relude" 1594 | note: "'Map' is already exported from Relude" 1595 | rhs: Map 1596 | - warn: 1597 | lhs: Data.Sequence.Sequence 1598 | name: "Use 'Sequence' from Relude" 1599 | note: "'Sequence' is already exported from Relude" 1600 | rhs: Sequence 1601 | - warn: 1602 | lhs: Data.Set.Set 1603 | name: "Use 'Set' from Relude" 1604 | note: "'Set' is already exported from Relude" 1605 | rhs: Set 1606 | - warn: 1607 | lhs: Data.Tuple.swap 1608 | name: "Use 'swap' from Relude" 1609 | note: "'swap' is already exported from Relude" 1610 | rhs: swap 1611 | - warn: 1612 | lhs: Data.Vector.Vector 1613 | name: "Use 'Vector' from Relude" 1614 | note: "'Vector' is already exported from Relude" 1615 | rhs: Vector 1616 | - warn: 1617 | lhs: GHC.Exts.IsList 1618 | name: "Use 'IsList' from Relude" 1619 | note: "'IsList' is already exported from Relude" 1620 | rhs: IsList 1621 | - warn: 1622 | lhs: GHC.Exts.fromList 1623 | name: "Use 'fromList' from Relude" 1624 | note: "'fromList' is already exported from Relude" 1625 | rhs: fromList 1626 | - warn: 1627 | lhs: GHC.Exts.fromListN 1628 | name: "Use 'fromListN' from Relude" 1629 | note: "'fromListN' is already exported from Relude" 1630 | rhs: fromListN 1631 | - warn: 1632 | lhs: Debug.Trace.trace 1633 | name: "Use 'trace' from Relude" 1634 | note: "'trace' is already exported from Relude" 1635 | rhs: trace 1636 | - warn: 1637 | lhs: Debug.Trace.traceShow 1638 | name: "Use 'traceShow' from Relude" 1639 | note: "'traceShow' is already exported from Relude" 1640 | rhs: traceShow 1641 | - warn: 1642 | lhs: Debug.Trace.traceShowId 1643 | name: "Use 'traceShowId' from Relude" 1644 | note: "'traceShowId' is already exported from Relude" 1645 | rhs: traceShowId 1646 | - warn: 1647 | lhs: Debug.Trace.traceShowM 1648 | name: "Use 'traceShowM' from Relude" 1649 | note: "'traceShowM' is already exported from Relude" 1650 | rhs: traceShowM 1651 | - warn: 1652 | lhs: Debug.Trace.traceM 1653 | name: "Use 'traceM' from Relude" 1654 | note: "'traceM' is already exported from Relude" 1655 | rhs: traceM 1656 | - warn: 1657 | lhs: Debug.Trace.traceId 1658 | name: "Use 'traceId' from Relude" 1659 | note: "'traceId' is already exported from Relude" 1660 | rhs: traceId 1661 | - warn: 1662 | lhs: Control.DeepSeq.NFData 1663 | name: "Use 'NFData' from Relude" 1664 | note: "'NFData' is already exported from Relude" 1665 | rhs: NFData 1666 | - warn: 1667 | lhs: Control.DeepSeq.rnf 1668 | name: "Use 'rnf' from Relude" 1669 | note: "'rnf' is already exported from Relude" 1670 | rhs: rnf 1671 | - warn: 1672 | lhs: Control.DeepSeq.deepseq 1673 | name: "Use 'deepseq' from Relude" 1674 | note: "'deepseq' is already exported from Relude" 1675 | rhs: deepseq 1676 | - warn: 1677 | lhs: Control.DeepSeq.force 1678 | name: "Use 'force' from Relude" 1679 | note: "'force' is already exported from Relude" 1680 | rhs: force 1681 | - warn: 1682 | lhs: "(Control.DeepSeq.$!!)" 1683 | name: "Use '$!!' from Relude" 1684 | note: "Operator '($!!)' is already exported from Relude" 1685 | rhs: "($!!)" 1686 | - warn: 1687 | lhs: Control.Exception.Exception 1688 | name: "Use 'Exception' from Relude" 1689 | note: "'Exception' is already exported from Relude" 1690 | rhs: Exception 1691 | - warn: 1692 | lhs: Control.Exception.SomeException 1693 | name: "Use 'SomeException' from Relude" 1694 | note: "'SomeException' is already exported from Relude" 1695 | rhs: SomeException 1696 | - warn: 1697 | lhs: Control.Exception.toException 1698 | name: "Use 'toException' from Relude" 1699 | note: "'toException' is already exported from Relude" 1700 | rhs: toException 1701 | - warn: 1702 | lhs: Control.Exception.fromException 1703 | name: "Use 'fromException' from Relude" 1704 | note: "'fromException' is already exported from Relude" 1705 | rhs: fromException 1706 | - warn: 1707 | lhs: Control.Exception.displayException 1708 | name: "Use 'displayException' from Relude" 1709 | note: "'displayException' is already exported from Relude" 1710 | rhs: displayException 1711 | - warn: 1712 | lhs: Data.Foldable.asum 1713 | name: "Use 'asum' from Relude" 1714 | note: "'asum' is already exported from Relude" 1715 | rhs: asum 1716 | - warn: 1717 | lhs: Data.Foldable.find 1718 | name: "Use 'find' from Relude" 1719 | note: "'find' is already exported from Relude" 1720 | rhs: find 1721 | - warn: 1722 | lhs: Data.Foldable.find 1723 | name: "Use 'find' from Relude" 1724 | note: "'find' is already exported from Relude" 1725 | rhs: find 1726 | - warn: 1727 | lhs: Data.Foldable.fold 1728 | name: "Use 'fold' from Relude" 1729 | note: "'fold' is already exported from Relude" 1730 | rhs: fold 1731 | - warn: 1732 | lhs: "Data.Foldable.foldl'" 1733 | name: "Use 'foldl'' from Relude" 1734 | note: "'foldl'' is already exported from Relude" 1735 | rhs: "foldl'" 1736 | - warn: 1737 | lhs: Data.Foldable.forM_ 1738 | name: "Use 'forM_' from Relude" 1739 | note: "'forM_' is already exported from Relude" 1740 | rhs: forM_ 1741 | - warn: 1742 | lhs: Data.Foldable.for_ 1743 | name: "Use 'for_' from Relude" 1744 | note: "'for_' is already exported from Relude" 1745 | rhs: for_ 1746 | - warn: 1747 | lhs: Data.Foldable.sequenceA_ 1748 | name: "Use 'sequenceA_' from Relude" 1749 | note: "'sequenceA_' is already exported from Relude" 1750 | rhs: sequenceA_ 1751 | - warn: 1752 | lhs: Data.Foldable.toList 1753 | name: "Use 'toList' from Relude" 1754 | note: "'toList' is already exported from Relude" 1755 | rhs: toList 1756 | - warn: 1757 | lhs: Data.Foldable.traverse_ 1758 | name: "Use 'traverse_' from Relude" 1759 | note: "'traverse_' is already exported from Relude" 1760 | rhs: traverse_ 1761 | - warn: 1762 | lhs: Data.Traversable.forM 1763 | name: "Use 'forM' from Relude" 1764 | note: "'forM' is already exported from Relude" 1765 | rhs: forM 1766 | - warn: 1767 | lhs: Data.Traversable.mapAccumL 1768 | name: "Use 'mapAccumL' from Relude" 1769 | note: "'mapAccumL' is already exported from Relude" 1770 | rhs: mapAccumL 1771 | - warn: 1772 | lhs: Data.Traversable.mapAccumR 1773 | name: "Use 'mapAccumR' from Relude" 1774 | note: "'mapAccumR' is already exported from Relude" 1775 | rhs: mapAccumR 1776 | - warn: 1777 | lhs: "(Control.Arrow.&&&)" 1778 | name: "Use '&&&' from Relude" 1779 | note: "Operator '(&&&)' is already exported from Relude" 1780 | rhs: "(&&&)" 1781 | - warn: 1782 | lhs: "(Control.Category.>>>)" 1783 | name: "Use '>>>' from Relude" 1784 | note: "Operator '(>>>)' is already exported from Relude" 1785 | rhs: "(>>>)" 1786 | - warn: 1787 | lhs: "(Control.Category.<<<)" 1788 | name: "Use '<<<' from Relude" 1789 | note: "Operator '(<<<)' is already exported from Relude" 1790 | rhs: "(<<<)" 1791 | - warn: 1792 | lhs: Data.Function.fix 1793 | name: "Use 'fix' from Relude" 1794 | note: "'fix' is already exported from Relude" 1795 | rhs: fix 1796 | - warn: 1797 | lhs: Data.Function.on 1798 | name: "Use 'on' from Relude" 1799 | note: "'on' is already exported from Relude" 1800 | rhs: 'on' 1801 | - warn: 1802 | lhs: Data.Bifunctor.Bifunctor 1803 | name: "Use 'Bifunctor' from Relude" 1804 | note: "'Bifunctor' is already exported from Relude" 1805 | rhs: Bifunctor 1806 | - warn: 1807 | lhs: Data.Bifunctor.bimap 1808 | name: "Use 'bimap' from Relude" 1809 | note: "'bimap' is already exported from Relude" 1810 | rhs: bimap 1811 | - warn: 1812 | lhs: Data.Bifunctor.first 1813 | name: "Use 'first' from Relude" 1814 | note: "'first' is already exported from Relude" 1815 | rhs: first 1816 | - warn: 1817 | lhs: Data.Bifunctor.second 1818 | name: "Use 'second' from Relude" 1819 | note: "'second' is already exported from Relude" 1820 | rhs: second 1821 | - warn: 1822 | lhs: Data.Functor.void 1823 | name: "Use 'void' from Relude" 1824 | note: "'void' is already exported from Relude" 1825 | rhs: void 1826 | - warn: 1827 | lhs: "(Data.Functor.$>)" 1828 | name: "Use '$>' from Relude" 1829 | note: "Operator '($>)' is already exported from Relude" 1830 | rhs: "($>)" 1831 | - warn: 1832 | lhs: "(Data.Functor.<&>)" 1833 | name: "Use '<&>' from Relude" 1834 | note: "Operator '(<&>)' is already exported from Relude" 1835 | rhs: "(<&>)" 1836 | - warn: 1837 | lhs: Data.Functor.Compose.Compose 1838 | name: "Use 'Compose' from Relude" 1839 | note: "'Compose' is already exported from Relude" 1840 | rhs: Compose 1841 | - warn: 1842 | lhs: Data.Functor.Compose.getCompose 1843 | name: "Use 'getCompose' from Relude" 1844 | note: "'getCompose' is already exported from Relude" 1845 | rhs: getCompose 1846 | - warn: 1847 | lhs: Data.Functor.Identity.Identity 1848 | name: "Use 'Identity' from Relude" 1849 | note: "'Identity' is already exported from Relude" 1850 | rhs: Identity 1851 | - warn: 1852 | lhs: Data.Functor.Identity.runIdentity 1853 | name: "Use 'runIdentity' from Relude" 1854 | note: "'runIdentity' is already exported from Relude" 1855 | rhs: runIdentity 1856 | - warn: 1857 | lhs: Control.Concurrent.MVar.MVar 1858 | name: "Use 'MVar' from Relude" 1859 | note: "'MVar' is already exported from Relude" 1860 | rhs: MVar 1861 | - warn: 1862 | lhs: Control.Concurrent.MVar.newEmptyMVar 1863 | name: "Use 'newEmptyMVar' from Relude" 1864 | note: "'newEmptyMVar' is already exported from Relude" 1865 | rhs: newEmptyMVar 1866 | - warn: 1867 | lhs: Control.Concurrent.MVar.newMVar 1868 | name: "Use 'newMVar' from Relude" 1869 | note: "'newMVar' is already exported from Relude" 1870 | rhs: newMVar 1871 | - warn: 1872 | lhs: Control.Concurrent.MVar.putMVar 1873 | name: "Use 'putMVar' from Relude" 1874 | note: "'putMVar' is already exported from Relude" 1875 | rhs: putMVar 1876 | - warn: 1877 | lhs: Control.Concurrent.MVar.readMVar 1878 | name: "Use 'readMVar' from Relude" 1879 | note: "'readMVar' is already exported from Relude" 1880 | rhs: readMVar 1881 | - warn: 1882 | lhs: Control.Concurrent.MVar.swapMVar 1883 | name: "Use 'swapMVar' from Relude" 1884 | note: "'swapMVar' is already exported from Relude" 1885 | rhs: swapMVar 1886 | - warn: 1887 | lhs: Control.Concurrent.MVar.takeMVar 1888 | name: "Use 'takeMVar' from Relude" 1889 | note: "'takeMVar' is already exported from Relude" 1890 | rhs: takeMVar 1891 | - warn: 1892 | lhs: Control.Concurrent.MVar.tryPutMVar 1893 | name: "Use 'tryPutMVar' from Relude" 1894 | note: "'tryPutMVar' is already exported from Relude" 1895 | rhs: tryPutMVar 1896 | - warn: 1897 | lhs: Control.Concurrent.MVar.tryReadMVar 1898 | name: "Use 'tryReadMVar' from Relude" 1899 | note: "'tryReadMVar' is already exported from Relude" 1900 | rhs: tryReadMVar 1901 | - warn: 1902 | lhs: Control.Concurrent.MVar.tryTakeMVar 1903 | name: "Use 'tryTakeMVar' from Relude" 1904 | note: "'tryTakeMVar' is already exported from Relude" 1905 | rhs: tryTakeMVar 1906 | - warn: 1907 | lhs: Control.Monad.STM.STM 1908 | name: "Use 'STM' from Relude" 1909 | note: "'STM' is already exported from Relude" 1910 | rhs: STM 1911 | - warn: 1912 | lhs: Control.Monad.STM.atomically 1913 | name: "Use 'atomically' from Relude" 1914 | note: "'atomically' is already exported from Relude" 1915 | rhs: atomically 1916 | - warn: 1917 | lhs: Control.Monad.STM.throwSTM 1918 | name: "Use 'throwSTM' from Relude" 1919 | note: "'throwSTM' is already exported from Relude" 1920 | rhs: throwSTM 1921 | - warn: 1922 | lhs: Control.Monad.STM.catchSTM 1923 | name: "Use 'catchSTM' from Relude" 1924 | note: "'catchSTM' is already exported from Relude" 1925 | rhs: catchSTM 1926 | - warn: 1927 | lhs: Control.Concurrent.STM.TVar.TVar 1928 | name: "Use 'TVar' from Relude" 1929 | note: "'TVar' is already exported from Relude" 1930 | rhs: TVar 1931 | - warn: 1932 | lhs: Control.Concurrent.STM.TVar.newTVarIO 1933 | name: "Use 'newTVarIO' from Relude" 1934 | note: "'newTVarIO' is already exported from Relude" 1935 | rhs: newTVarIO 1936 | - warn: 1937 | lhs: Control.Concurrent.STM.TVar.readTVarIO 1938 | name: "Use 'readTVarIO' from Relude" 1939 | note: "'readTVarIO' is already exported from Relude" 1940 | rhs: readTVarIO 1941 | - warn: 1942 | lhs: "Control.Concurrent.STM.TVar.modifyTVar'" 1943 | name: "Use 'modifyTVar'' from Relude" 1944 | note: "'modifyTVar'' is already exported from Relude" 1945 | rhs: "modifyTVar'" 1946 | - warn: 1947 | lhs: Control.Concurrent.STM.TVar.newTVar 1948 | name: "Use 'newTVar' from Relude" 1949 | note: "'newTVar' is already exported from Relude" 1950 | rhs: newTVar 1951 | - warn: 1952 | lhs: Control.Concurrent.STM.TVar.readTVar 1953 | name: "Use 'readTVar' from Relude" 1954 | note: "'readTVar' is already exported from Relude" 1955 | rhs: readTVar 1956 | - warn: 1957 | lhs: Control.Concurrent.STM.TVar.writeTVar 1958 | name: "Use 'writeTVar' from Relude" 1959 | note: "'writeTVar' is already exported from Relude" 1960 | rhs: writeTVar 1961 | - warn: 1962 | lhs: Control.Concurrent.STM.TMVar.TMVar 1963 | name: "Use 'TMVar' from Relude" 1964 | note: "'TMVar' is already exported from Relude" 1965 | rhs: TMVar 1966 | - warn: 1967 | lhs: Control.Concurrent.STM.TMVar.newTMVar 1968 | name: "Use 'newTMVar' from Relude" 1969 | note: "'newTMVar' is already exported from Relude" 1970 | rhs: newTMVar 1971 | - warn: 1972 | lhs: Control.Concurrent.STM.TMVar.newEmptyTMVar 1973 | name: "Use 'newEmptyTMVar' from Relude" 1974 | note: "'newEmptyTMVar' is already exported from Relude" 1975 | rhs: newEmptyTMVar 1976 | - warn: 1977 | lhs: Control.Concurrent.STM.TMVar.newTMVarIO 1978 | name: "Use 'newTMVarIO' from Relude" 1979 | note: "'newTMVarIO' is already exported from Relude" 1980 | rhs: newTMVarIO 1981 | - warn: 1982 | lhs: Control.Concurrent.STM.TMVar.newEmptyTMVarIO 1983 | name: "Use 'newEmptyTMVarIO' from Relude" 1984 | note: "'newEmptyTMVarIO' is already exported from Relude" 1985 | rhs: newEmptyTMVarIO 1986 | - warn: 1987 | lhs: Control.Concurrent.STM.TMVar.takeTMVar 1988 | name: "Use 'takeTMVar' from Relude" 1989 | note: "'takeTMVar' is already exported from Relude" 1990 | rhs: takeTMVar 1991 | - warn: 1992 | lhs: Control.Concurrent.STM.TMVar.putTMVar 1993 | name: "Use 'putTMVar' from Relude" 1994 | note: "'putTMVar' is already exported from Relude" 1995 | rhs: putTMVar 1996 | - warn: 1997 | lhs: Control.Concurrent.STM.TMVar.readTMVar 1998 | name: "Use 'readTMVar' from Relude" 1999 | note: "'readTMVar' is already exported from Relude" 2000 | rhs: readTMVar 2001 | - warn: 2002 | lhs: Control.Concurrent.STM.TMVar.tryReadTMVar 2003 | name: "Use 'tryReadTMVar' from Relude" 2004 | note: "'tryReadTMVar' is already exported from Relude" 2005 | rhs: tryReadTMVar 2006 | - warn: 2007 | lhs: Control.Concurrent.STM.TMVar.swapTMVar 2008 | name: "Use 'swapTMVar' from Relude" 2009 | note: "'swapTMVar' is already exported from Relude" 2010 | rhs: swapTMVar 2011 | - warn: 2012 | lhs: Control.Concurrent.STM.TMVar.tryTakeTMVar 2013 | name: "Use 'tryTakeTMVar' from Relude" 2014 | note: "'tryTakeTMVar' is already exported from Relude" 2015 | rhs: tryTakeTMVar 2016 | - warn: 2017 | lhs: Control.Concurrent.STM.TMVar.tryPutTMVar 2018 | name: "Use 'tryPutTMVar' from Relude" 2019 | note: "'tryPutTMVar' is already exported from Relude" 2020 | rhs: tryPutTMVar 2021 | - warn: 2022 | lhs: Control.Concurrent.STM.TMVar.isEmptyTMVar 2023 | name: "Use 'isEmptyTMVar' from Relude" 2024 | note: "'isEmptyTMVar' is already exported from Relude" 2025 | rhs: isEmptyTMVar 2026 | - warn: 2027 | lhs: Control.Concurrent.STM.TMVar.mkWeakTMVar 2028 | name: "Use 'mkWeakTMVar' from Relude" 2029 | note: "'mkWeakTMVar' is already exported from Relude" 2030 | rhs: mkWeakTMVar 2031 | - warn: 2032 | lhs: Data.IORef.IORef 2033 | name: "Use 'IORef' from Relude" 2034 | note: "'IORef' is already exported from Relude" 2035 | rhs: IORef 2036 | - warn: 2037 | lhs: Data.IORef.atomicModifyIORef 2038 | name: "Use 'atomicModifyIORef' from Relude" 2039 | note: "'atomicModifyIORef' is already exported from Relude" 2040 | rhs: atomicModifyIORef 2041 | - warn: 2042 | lhs: "Data.IORef.atomicModifyIORef'" 2043 | name: "Use 'atomicModifyIORef'' from Relude" 2044 | note: "'atomicModifyIORef'' is already exported from Relude" 2045 | rhs: "atomicModifyIORef'" 2046 | - warn: 2047 | lhs: Data.IORef.atomicWriteIORef 2048 | name: "Use 'atomicWriteIORef' from Relude" 2049 | note: "'atomicWriteIORef' is already exported from Relude" 2050 | rhs: atomicWriteIORef 2051 | - warn: 2052 | lhs: Data.IORef.modifyIORef 2053 | name: "Use 'modifyIORef' from Relude" 2054 | note: "'modifyIORef' is already exported from Relude" 2055 | rhs: modifyIORef 2056 | - warn: 2057 | lhs: "Data.IORef.modifyIORef'" 2058 | name: "Use 'modifyIORef'' from Relude" 2059 | note: "'modifyIORef'' is already exported from Relude" 2060 | rhs: "modifyIORef'" 2061 | - warn: 2062 | lhs: Data.IORef.newIORef 2063 | name: "Use 'newIORef' from Relude" 2064 | note: "'newIORef' is already exported from Relude" 2065 | rhs: newIORef 2066 | - warn: 2067 | lhs: Data.IORef.readIORef 2068 | name: "Use 'readIORef' from Relude" 2069 | note: "'readIORef' is already exported from Relude" 2070 | rhs: readIORef 2071 | - warn: 2072 | lhs: Data.IORef.writeIORef 2073 | name: "Use 'writeIORef' from Relude" 2074 | note: "'writeIORef' is already exported from Relude" 2075 | rhs: writeIORef 2076 | - warn: 2077 | lhs: "atomicModifyIORef ref (\\a -> (f a, ()))" 2078 | rhs: atomicModifyIORef_ ref f 2079 | - warn: 2080 | lhs: "atomicModifyIORef ref $ \\a -> (f a, ())" 2081 | rhs: atomicModifyIORef_ ref f 2082 | - warn: 2083 | lhs: "atomicModifyIORef' ref $ \\a -> (f a, ())" 2084 | rhs: "atomicModifyIORef'_ ref f" 2085 | - warn: 2086 | lhs: "atomicModifyIORef' ref (\\a -> (f a, ()))" 2087 | rhs: "atomicModifyIORef'_ ref f" 2088 | - warn: 2089 | lhs: Data.Text.IO.getLine 2090 | name: "Use 'getLine' from Relude" 2091 | note: "'getLine' is already exported from Relude" 2092 | rhs: getLine 2093 | - warn: 2094 | lhs: System.IO.hFlush 2095 | name: "Use 'hFlush' from Relude" 2096 | note: "'hFlush' is already exported from Relude" 2097 | rhs: hFlush 2098 | - warn: 2099 | lhs: System.IO.hIsEOF 2100 | name: "Use 'hIsEOF' from Relude" 2101 | note: "'hIsEOF' is already exported from Relude" 2102 | rhs: hIsEOF 2103 | - warn: 2104 | lhs: System.IO.hSetBuffering 2105 | name: "Use 'hSetBuffering' from Relude" 2106 | note: "'hSetBuffering' is already exported from Relude" 2107 | rhs: hSetBuffering 2108 | - warn: 2109 | lhs: System.IO.hGetBuffering 2110 | name: "Use 'hGetBuffering' from Relude" 2111 | note: "'hGetBuffering' is already exported from Relude" 2112 | rhs: hGetBuffering 2113 | - warn: 2114 | lhs: System.IO.Handle 2115 | name: "Use 'Handle' from Relude" 2116 | note: "'Handle' is already exported from Relude" 2117 | rhs: Handle 2118 | - warn: 2119 | lhs: System.IO.stdin 2120 | name: "Use 'stdin' from Relude" 2121 | note: "'stdin' is already exported from Relude" 2122 | rhs: stdin 2123 | - warn: 2124 | lhs: System.IO.stdout 2125 | name: "Use 'stdout' from Relude" 2126 | note: "'stdout' is already exported from Relude" 2127 | rhs: stdout 2128 | - warn: 2129 | lhs: System.IO.stderr 2130 | name: "Use 'stderr' from Relude" 2131 | note: "'stderr' is already exported from Relude" 2132 | rhs: stderr 2133 | - warn: 2134 | lhs: System.IO.withFile 2135 | name: "Use 'withFile' from Relude" 2136 | note: "'withFile' is already exported from Relude" 2137 | rhs: withFile 2138 | - warn: 2139 | lhs: System.IO.BufferMode 2140 | name: "Use 'BufferMode' from Relude" 2141 | note: "'BufferMode' is already exported from Relude" 2142 | rhs: BufferMode 2143 | - warn: 2144 | lhs: System.Environment.getArgs 2145 | name: "Use 'getArgs' from Relude" 2146 | note: "'getArgs' is already exported from Relude" 2147 | rhs: getArgs 2148 | - warn: 2149 | lhs: System.Environment.lookupEnv 2150 | name: "Use 'lookupEnv' from Relude" 2151 | note: "'lookupEnv' is already exported from Relude" 2152 | rhs: lookupEnv 2153 | - warn: 2154 | lhs: Data.List.genericDrop 2155 | name: "Use 'genericDrop' from Relude" 2156 | note: "'genericDrop' is already exported from Relude" 2157 | rhs: genericDrop 2158 | - warn: 2159 | lhs: Data.List.genericLength 2160 | name: "Use 'genericLength' from Relude" 2161 | note: "'genericLength' is already exported from Relude" 2162 | rhs: genericLength 2163 | - warn: 2164 | lhs: Data.List.genericReplicate 2165 | name: "Use 'genericReplicate' from Relude" 2166 | note: "'genericReplicate' is already exported from Relude" 2167 | rhs: genericReplicate 2168 | - warn: 2169 | lhs: Data.List.genericSplitAt 2170 | name: "Use 'genericSplitAt' from Relude" 2171 | note: "'genericSplitAt' is already exported from Relude" 2172 | rhs: genericSplitAt 2173 | - warn: 2174 | lhs: Data.List.genericTake 2175 | name: "Use 'genericTake' from Relude" 2176 | note: "'genericTake' is already exported from Relude" 2177 | rhs: genericTake 2178 | - warn: 2179 | lhs: Data.List.group 2180 | name: "Use 'group' from Relude" 2181 | note: "'group' is already exported from Relude" 2182 | rhs: group 2183 | - warn: 2184 | lhs: Data.List.inits 2185 | name: "Use 'inits' from Relude" 2186 | note: "'inits' is already exported from Relude" 2187 | rhs: inits 2188 | - warn: 2189 | lhs: Data.List.intercalate 2190 | name: "Use 'intercalate' from Relude" 2191 | note: "'intercalate' is already exported from Relude" 2192 | rhs: intercalate 2193 | - warn: 2194 | lhs: Data.List.intersperse 2195 | name: "Use 'intersperse' from Relude" 2196 | note: "'intersperse' is already exported from Relude" 2197 | rhs: intersperse 2198 | - warn: 2199 | lhs: Data.List.isPrefixOf 2200 | name: "Use 'isPrefixOf' from Relude" 2201 | note: "'isPrefixOf' is already exported from Relude" 2202 | rhs: isPrefixOf 2203 | - warn: 2204 | lhs: Data.List.permutations 2205 | name: "Use 'permutations' from Relude" 2206 | note: "'permutations' is already exported from Relude" 2207 | rhs: permutations 2208 | - warn: 2209 | lhs: "Data.List.scanl'" 2210 | name: "Use 'scanl'' from Relude" 2211 | note: "'scanl'' is already exported from Relude" 2212 | rhs: "scanl'" 2213 | - warn: 2214 | lhs: Data.List.sort 2215 | name: "Use 'sort' from Relude" 2216 | note: "'sort' is already exported from Relude" 2217 | rhs: sort 2218 | - warn: 2219 | lhs: Data.List.sortBy 2220 | name: "Use 'sortBy' from Relude" 2221 | note: "'sortBy' is already exported from Relude" 2222 | rhs: sortBy 2223 | - warn: 2224 | lhs: Data.List.sortOn 2225 | name: "Use 'sortOn' from Relude" 2226 | note: "'sortOn' is already exported from Relude" 2227 | rhs: sortOn 2228 | - warn: 2229 | lhs: Data.List.subsequences 2230 | name: "Use 'subsequences' from Relude" 2231 | note: "'subsequences' is already exported from Relude" 2232 | rhs: subsequences 2233 | - warn: 2234 | lhs: Data.List.tails 2235 | name: "Use 'tails' from Relude" 2236 | note: "'tails' is already exported from Relude" 2237 | rhs: tails 2238 | - warn: 2239 | lhs: Data.List.transpose 2240 | name: "Use 'transpose' from Relude" 2241 | note: "'transpose' is already exported from Relude" 2242 | rhs: transpose 2243 | - warn: 2244 | lhs: Data.List.uncons 2245 | name: "Use 'uncons' from Relude" 2246 | note: "'uncons' is already exported from Relude" 2247 | rhs: uncons 2248 | - warn: 2249 | lhs: Data.List.unfoldr 2250 | name: "Use 'unfoldr' from Relude" 2251 | note: "'unfoldr' is already exported from Relude" 2252 | rhs: unfoldr 2253 | - warn: 2254 | lhs: Data.List.NonEmpty.NonEmpty 2255 | name: "Use 'NonEmpty' from Relude" 2256 | note: "'NonEmpty' is already exported from Relude" 2257 | rhs: NonEmpty 2258 | - warn: 2259 | lhs: "(Data.List.NonEmpty.:|)" 2260 | name: "Use ':|' from Relude" 2261 | note: "Operator '(:|)' is already exported from Relude" 2262 | rhs: "(:|)" 2263 | - warn: 2264 | lhs: Data.List.NonEmpty.nonEmpty 2265 | name: "Use 'nonEmpty' from Relude" 2266 | note: "'nonEmpty' is already exported from Relude" 2267 | rhs: nonEmpty 2268 | - warn: 2269 | lhs: Data.List.NonEmpty.head 2270 | name: "Use 'head' from Relude" 2271 | note: "'head' is already exported from Relude" 2272 | rhs: head 2273 | - warn: 2274 | lhs: Data.List.NonEmpty.init 2275 | name: "Use 'init' from Relude" 2276 | note: "'init' is already exported from Relude" 2277 | rhs: init 2278 | - warn: 2279 | lhs: Data.List.NonEmpty.last 2280 | name: "Use 'last' from Relude" 2281 | note: "'last' is already exported from Relude" 2282 | rhs: last 2283 | - warn: 2284 | lhs: Data.List.NonEmpty.tail 2285 | name: "Use 'tail' from Relude" 2286 | note: "'tail' is already exported from Relude" 2287 | rhs: tail 2288 | - warn: 2289 | lhs: GHC.Exts.sortWith 2290 | name: "Use 'sortWith' from Relude" 2291 | note: "'sortWith' is already exported from Relude" 2292 | rhs: sortWith 2293 | - warn: 2294 | lhs: Control.Monad.Except.ExceptT 2295 | name: "Use 'ExceptT' from Relude" 2296 | note: "'ExceptT' is already exported from Relude" 2297 | rhs: ExceptT 2298 | - warn: 2299 | lhs: Control.Monad.Except.runExceptT 2300 | name: "Use 'runExceptT' from Relude" 2301 | note: "'runExceptT' is already exported from Relude" 2302 | rhs: runExceptT 2303 | - warn: 2304 | lhs: Control.Monad.Reader.MonadReader 2305 | name: "Use 'MonadReader' from Relude" 2306 | note: "'MonadReader' is already exported from Relude" 2307 | rhs: MonadReader 2308 | - warn: 2309 | lhs: Control.Monad.Reader.Reader 2310 | name: "Use 'Reader' from Relude" 2311 | note: "'Reader' is already exported from Relude" 2312 | rhs: Reader 2313 | - warn: 2314 | lhs: Control.Monad.Reader.ReaderT 2315 | name: "Use 'ReaderT' from Relude" 2316 | note: "'ReaderT' is already exported from Relude" 2317 | rhs: ReaderT 2318 | - warn: 2319 | lhs: Control.Monad.Reader.runReaderT 2320 | name: "Use 'runReaderT' from Relude" 2321 | note: "'runReaderT' is already exported from Relude" 2322 | rhs: runReaderT 2323 | - warn: 2324 | lhs: Control.Monad.Reader.ask 2325 | name: "Use 'ask' from Relude" 2326 | note: "'ask' is already exported from Relude" 2327 | rhs: ask 2328 | - warn: 2329 | lhs: Control.Monad.Reader.asks 2330 | name: "Use 'asks' from Relude" 2331 | note: "'asks' is already exported from Relude" 2332 | rhs: asks 2333 | - warn: 2334 | lhs: Control.Monad.Reader.local 2335 | name: "Use 'local' from Relude" 2336 | note: "'local' is already exported from Relude" 2337 | rhs: local 2338 | - warn: 2339 | lhs: Control.Monad.Reader.reader 2340 | name: "Use 'reader' from Relude" 2341 | note: "'reader' is already exported from Relude" 2342 | rhs: reader 2343 | - warn: 2344 | lhs: Control.Monad.Reader.runReader 2345 | name: "Use 'runReader' from Relude" 2346 | note: "'runReader' is already exported from Relude" 2347 | rhs: runReader 2348 | - warn: 2349 | lhs: Control.Monad.Reader.withReader 2350 | name: "Use 'withReader' from Relude" 2351 | note: "'withReader' is already exported from Relude" 2352 | rhs: withReader 2353 | - warn: 2354 | lhs: Control.Monad.Reader.withReaderT 2355 | name: "Use 'withReaderT' from Relude" 2356 | note: "'withReaderT' is already exported from Relude" 2357 | rhs: withReaderT 2358 | - warn: 2359 | lhs: Control.Monad.State.Strict.MonadState 2360 | name: "Use 'MonadState' from Relude" 2361 | note: "'MonadState' is already exported from Relude" 2362 | rhs: MonadState 2363 | - warn: 2364 | lhs: Control.Monad.State.Strict.State 2365 | name: "Use 'State' from Relude" 2366 | note: "'State' is already exported from Relude" 2367 | rhs: State 2368 | - warn: 2369 | lhs: Control.Monad.State.Strict.StateT 2370 | name: "Use 'StateT' from Relude" 2371 | note: "'StateT' is already exported from Relude" 2372 | rhs: StateT 2373 | - warn: 2374 | lhs: Control.Monad.State.Strict.runStateT 2375 | name: "Use 'runStateT' from Relude" 2376 | note: "'runStateT' is already exported from Relude" 2377 | rhs: runStateT 2378 | - warn: 2379 | lhs: Control.Monad.State.Strict.evalState 2380 | name: "Use 'evalState' from Relude" 2381 | note: "'evalState' is already exported from Relude" 2382 | rhs: evalState 2383 | - warn: 2384 | lhs: Control.Monad.State.Strict.evalStateT 2385 | name: "Use 'evalStateT' from Relude" 2386 | note: "'evalStateT' is already exported from Relude" 2387 | rhs: evalStateT 2388 | - warn: 2389 | lhs: Control.Monad.State.Strict.execState 2390 | name: "Use 'execState' from Relude" 2391 | note: "'execState' is already exported from Relude" 2392 | rhs: execState 2393 | - warn: 2394 | lhs: Control.Monad.State.Strict.execStateT 2395 | name: "Use 'execStateT' from Relude" 2396 | note: "'execStateT' is already exported from Relude" 2397 | rhs: execStateT 2398 | - warn: 2399 | lhs: Control.Monad.State.Strict.get 2400 | name: "Use 'get' from Relude" 2401 | note: "'get' is already exported from Relude" 2402 | rhs: get 2403 | - warn: 2404 | lhs: Control.Monad.State.Strict.gets 2405 | name: "Use 'gets' from Relude" 2406 | note: "'gets' is already exported from Relude" 2407 | rhs: gets 2408 | - warn: 2409 | lhs: Control.Monad.State.Strict.modify 2410 | name: "Use 'modify' from Relude" 2411 | note: "'modify' is already exported from Relude" 2412 | rhs: modify 2413 | - warn: 2414 | lhs: "Control.Monad.State.Strict.modify'" 2415 | name: "Use 'modify'' from Relude" 2416 | note: "'modify'' is already exported from Relude" 2417 | rhs: "modify'" 2418 | - warn: 2419 | lhs: Control.Monad.State.Strict.put 2420 | name: "Use 'put' from Relude" 2421 | note: "'put' is already exported from Relude" 2422 | rhs: put 2423 | - warn: 2424 | lhs: Control.Monad.State.Strict.runState 2425 | name: "Use 'runState' from Relude" 2426 | note: "'runState' is already exported from Relude" 2427 | rhs: runState 2428 | - warn: 2429 | lhs: Control.Monad.State.Strict.state 2430 | name: "Use 'state' from Relude" 2431 | note: "'state' is already exported from Relude" 2432 | rhs: state 2433 | - warn: 2434 | lhs: Control.Monad.State.Strict.withState 2435 | name: "Use 'withState' from Relude" 2436 | note: "'withState' is already exported from Relude" 2437 | rhs: withState 2438 | - warn: 2439 | lhs: Control.Monad.Trans.MonadIO 2440 | name: "Use 'MonadIO' from Relude" 2441 | note: "'MonadIO' is already exported from Relude" 2442 | rhs: MonadIO 2443 | - warn: 2444 | lhs: Control.Monad.Trans.MonadTrans 2445 | name: "Use 'MonadTrans' from Relude" 2446 | note: "'MonadTrans' is already exported from Relude" 2447 | rhs: MonadTrans 2448 | - warn: 2449 | lhs: Control.Monad.Trans.lift 2450 | name: "Use 'lift' from Relude" 2451 | note: "'lift' is already exported from Relude" 2452 | rhs: lift 2453 | - warn: 2454 | lhs: Control.Monad.Trans.liftIO 2455 | name: "Use 'liftIO' from Relude" 2456 | note: "'liftIO' is already exported from Relude" 2457 | rhs: liftIO 2458 | - warn: 2459 | lhs: Control.Monad.Trans.Identity.IdentityT 2460 | name: "Use 'IdentityT' from Relude" 2461 | note: "'IdentityT' is already exported from Relude" 2462 | rhs: IdentityT 2463 | - warn: 2464 | lhs: Control.Monad.Trans.Identity.runIdentityT 2465 | name: "Use 'runIdentityT' from Relude" 2466 | note: "'runIdentityT' is already exported from Relude" 2467 | rhs: runIdentityT 2468 | - warn: 2469 | lhs: Control.Monad.Trans.Maybe.MaybeT 2470 | name: "Use 'MaybeT' from Relude" 2471 | note: "'MaybeT' is already exported from Relude" 2472 | rhs: MaybeT 2473 | - warn: 2474 | lhs: Control.Monad.Trans.Maybe.maybeToExceptT 2475 | name: "Use 'maybeToExceptT' from Relude" 2476 | note: "'maybeToExceptT' is already exported from Relude" 2477 | rhs: maybeToExceptT 2478 | - warn: 2479 | lhs: Control.Monad.Trans.Maybe.exceptToMaybeT 2480 | name: "Use 'exceptToMaybeT' from Relude" 2481 | note: "'exceptToMaybeT' is already exported from Relude" 2482 | rhs: exceptToMaybeT 2483 | - warn: 2484 | lhs: Control.Monad.MonadPlus 2485 | name: "Use 'MonadPlus' from Relude" 2486 | note: "'MonadPlus' is already exported from Relude" 2487 | rhs: MonadPlus 2488 | - warn: 2489 | lhs: Control.Monad.mzero 2490 | name: "Use 'mzero' from Relude" 2491 | note: "'mzero' is already exported from Relude" 2492 | rhs: mzero 2493 | - warn: 2494 | lhs: Control.Monad.mplus 2495 | name: "Use 'mplus' from Relude" 2496 | note: "'mplus' is already exported from Relude" 2497 | rhs: mplus 2498 | - warn: 2499 | lhs: Control.Monad.filterM 2500 | name: "Use 'filterM' from Relude" 2501 | note: "'filterM' is already exported from Relude" 2502 | rhs: filterM 2503 | - warn: 2504 | lhs: Control.Monad.forever 2505 | name: "Use 'forever' from Relude" 2506 | note: "'forever' is already exported from Relude" 2507 | rhs: forever 2508 | - warn: 2509 | lhs: Control.Monad.join 2510 | name: "Use 'join' from Relude" 2511 | note: "'join' is already exported from Relude" 2512 | rhs: join 2513 | - warn: 2514 | lhs: Control.Monad.mapAndUnzipM 2515 | name: "Use 'mapAndUnzipM' from Relude" 2516 | note: "'mapAndUnzipM' is already exported from Relude" 2517 | rhs: mapAndUnzipM 2518 | - warn: 2519 | lhs: Control.Monad.mfilter 2520 | name: "Use 'mfilter' from Relude" 2521 | note: "'mfilter' is already exported from Relude" 2522 | rhs: mfilter 2523 | - warn: 2524 | lhs: Control.Monad.replicateM 2525 | name: "Use 'replicateM' from Relude" 2526 | note: "'replicateM' is already exported from Relude" 2527 | rhs: replicateM 2528 | - warn: 2529 | lhs: Control.Monad.replicateM_ 2530 | name: "Use 'replicateM_' from Relude" 2531 | note: "'replicateM_' is already exported from Relude" 2532 | rhs: replicateM_ 2533 | - warn: 2534 | lhs: Control.Monad.zipWithM 2535 | name: "Use 'zipWithM' from Relude" 2536 | note: "'zipWithM' is already exported from Relude" 2537 | rhs: zipWithM 2538 | - warn: 2539 | lhs: Control.Monad.zipWithM_ 2540 | name: "Use 'zipWithM_' from Relude" 2541 | note: "'zipWithM_' is already exported from Relude" 2542 | rhs: zipWithM_ 2543 | - warn: 2544 | lhs: "(Control.Monad.<$!>)" 2545 | name: "Use '<$!>' from Relude" 2546 | note: "Operator '(<$!>)' is already exported from Relude" 2547 | rhs: "(<$!>)" 2548 | - warn: 2549 | lhs: "(Control.Monad.<=<)" 2550 | name: "Use '<=<' from Relude" 2551 | note: "Operator '(<=<)' is already exported from Relude" 2552 | rhs: "(<=<)" 2553 | - warn: 2554 | lhs: "(Control.Monad.=<<)" 2555 | name: "Use '=<<' from Relude" 2556 | note: "Operator '(=<<)' is already exported from Relude" 2557 | rhs: "(=<<)" 2558 | - warn: 2559 | lhs: "(Control.Monad.>=>)" 2560 | name: "Use '>=>' from Relude" 2561 | note: "Operator '(>=>)' is already exported from Relude" 2562 | rhs: "(>=>)" 2563 | - warn: 2564 | lhs: Control.Monad.Fail.MonadFail 2565 | name: "Use 'MonadFail' from Relude" 2566 | note: "'MonadFail' is already exported from Relude" 2567 | rhs: MonadFail 2568 | - warn: 2569 | lhs: Data.Maybe.catMaybes 2570 | name: "Use 'catMaybes' from Relude" 2571 | note: "'catMaybes' is already exported from Relude" 2572 | rhs: catMaybes 2573 | - warn: 2574 | lhs: Data.Maybe.fromMaybe 2575 | name: "Use 'fromMaybe' from Relude" 2576 | note: "'fromMaybe' is already exported from Relude" 2577 | rhs: fromMaybe 2578 | - warn: 2579 | lhs: Data.Maybe.isJust 2580 | name: "Use 'isJust' from Relude" 2581 | note: "'isJust' is already exported from Relude" 2582 | rhs: isJust 2583 | - warn: 2584 | lhs: Data.Maybe.isNothing 2585 | name: "Use 'isNothing' from Relude" 2586 | note: "'isNothing' is already exported from Relude" 2587 | rhs: isNothing 2588 | - warn: 2589 | lhs: Data.Maybe.listToMaybe 2590 | name: "Use 'listToMaybe' from Relude" 2591 | note: "'listToMaybe' is already exported from Relude" 2592 | rhs: listToMaybe 2593 | - warn: 2594 | lhs: Data.Maybe.mapMaybe 2595 | name: "Use 'mapMaybe' from Relude" 2596 | note: "'mapMaybe' is already exported from Relude" 2597 | rhs: mapMaybe 2598 | - warn: 2599 | lhs: Data.Maybe.maybeToList 2600 | name: "Use 'maybeToList' from Relude" 2601 | note: "'maybeToList' is already exported from Relude" 2602 | rhs: maybeToList 2603 | - warn: 2604 | lhs: Data.Either.isLeft 2605 | name: "Use 'isLeft' from Relude" 2606 | note: "'isLeft' is already exported from Relude" 2607 | rhs: isLeft 2608 | - warn: 2609 | lhs: Data.Either.isRight 2610 | name: "Use 'isRight' from Relude" 2611 | note: "'isRight' is already exported from Relude" 2612 | rhs: isRight 2613 | - warn: 2614 | lhs: Data.Either.lefts 2615 | name: "Use 'lefts' from Relude" 2616 | note: "'lefts' is already exported from Relude" 2617 | rhs: lefts 2618 | - warn: 2619 | lhs: Data.Either.partitionEithers 2620 | name: "Use 'partitionEithers' from Relude" 2621 | note: "'partitionEithers' is already exported from Relude" 2622 | rhs: partitionEithers 2623 | - warn: 2624 | lhs: Data.Either.rights 2625 | name: "Use 'rights' from Relude" 2626 | note: "'rights' is already exported from Relude" 2627 | rhs: rights 2628 | - warn: 2629 | lhs: Data.Monoid.All 2630 | name: "Use 'All' from Relude" 2631 | note: "'All' is already exported from Relude" 2632 | rhs: All 2633 | - warn: 2634 | lhs: Data.Monoid.getAll 2635 | name: "Use 'getAll' from Relude" 2636 | note: "'getAll' is already exported from Relude" 2637 | rhs: getAll 2638 | - warn: 2639 | lhs: Data.Monoid.Alt 2640 | name: "Use 'Alt' from Relude" 2641 | note: "'Alt' is already exported from Relude" 2642 | rhs: Alt 2643 | - warn: 2644 | lhs: Data.Monoid.getAlt 2645 | name: "Use 'getAlt' from Relude" 2646 | note: "'getAlt' is already exported from Relude" 2647 | rhs: getAlt 2648 | - warn: 2649 | lhs: Data.Monoid.Any 2650 | name: "Use 'Any' from Relude" 2651 | note: "'Any' is already exported from Relude" 2652 | rhs: Any 2653 | - warn: 2654 | lhs: Data.Monoid.getAny 2655 | name: "Use 'getAny' from Relude" 2656 | note: "'getAny' is already exported from Relude" 2657 | rhs: getAny 2658 | - warn: 2659 | lhs: Data.Monoid.Ap 2660 | name: "Use 'Ap' from Relude" 2661 | note: "'Ap' is already exported from Relude" 2662 | rhs: Ap 2663 | - warn: 2664 | lhs: Data.Monoid.getAp 2665 | name: "Use 'getAp' from Relude" 2666 | note: "'getAp' is already exported from Relude" 2667 | rhs: getAp 2668 | - warn: 2669 | lhs: Data.Monoid.Dual 2670 | name: "Use 'Dual' from Relude" 2671 | note: "'Dual' is already exported from Relude" 2672 | rhs: Dual 2673 | - warn: 2674 | lhs: Data.Monoid.getDual 2675 | name: "Use 'getDual' from Relude" 2676 | note: "'getDual' is already exported from Relude" 2677 | rhs: getDual 2678 | - warn: 2679 | lhs: Data.Monoid.Endo 2680 | name: "Use 'Endo' from Relude" 2681 | note: "'Endo' is already exported from Relude" 2682 | rhs: Endo 2683 | - warn: 2684 | lhs: Data.Monoid.appEndo 2685 | name: "Use 'appEndo' from Relude" 2686 | note: "'appEndo' is already exported from Relude" 2687 | rhs: appEndo 2688 | - warn: 2689 | lhs: Data.Monoid.First 2690 | name: "Use 'First' from Relude" 2691 | note: "'First' is already exported from Relude" 2692 | rhs: First 2693 | - warn: 2694 | lhs: Data.Monoid.getFirst 2695 | name: "Use 'getFirst' from Relude" 2696 | note: "'getFirst' is already exported from Relude" 2697 | rhs: getFirst 2698 | - warn: 2699 | lhs: Data.Monoid.Last 2700 | name: "Use 'Last' from Relude" 2701 | note: "'Last' is already exported from Relude" 2702 | rhs: Last 2703 | - warn: 2704 | lhs: Data.Monoid.getLast 2705 | name: "Use 'getLast' from Relude" 2706 | note: "'getLast' is already exported from Relude" 2707 | rhs: getLast 2708 | - warn: 2709 | lhs: Data.Monoid.Product 2710 | name: "Use 'Product' from Relude" 2711 | note: "'Product' is already exported from Relude" 2712 | rhs: Product 2713 | - warn: 2714 | lhs: Data.Monoid.getProduct 2715 | name: "Use 'getProduct' from Relude" 2716 | note: "'getProduct' is already exported from Relude" 2717 | rhs: getProduct 2718 | - warn: 2719 | lhs: Data.Monoid.Sum 2720 | name: "Use 'Sum' from Relude" 2721 | note: "'Sum' is already exported from Relude" 2722 | rhs: Sum 2723 | - warn: 2724 | lhs: Data.Monoid.getSum 2725 | name: "Use 'getSum' from Relude" 2726 | note: "'getSum' is already exported from Relude" 2727 | rhs: getSum 2728 | - warn: 2729 | lhs: Data.Semigroup.Semigroup 2730 | name: "Use 'Semigroup' from Relude" 2731 | note: "'Semigroup' is already exported from Relude" 2732 | rhs: Semigroup 2733 | - warn: 2734 | lhs: Data.Semigroup.sconcat 2735 | name: "Use 'sconcat' from Relude" 2736 | note: "'sconcat' is already exported from Relude" 2737 | rhs: sconcat 2738 | - warn: 2739 | lhs: Data.Semigroup.stimes 2740 | name: "Use 'stimes' from Relude" 2741 | note: "'stimes' is already exported from Relude" 2742 | rhs: stimes 2743 | - warn: 2744 | lhs: "(Data.Semigroup.<>)" 2745 | name: "Use '<>' from Relude" 2746 | note: "Operator '(<>)' is already exported from Relude" 2747 | rhs: "(<>)" 2748 | - warn: 2749 | lhs: Data.Semigroup.WrappedMonoid 2750 | name: "Use 'WrappedMonoid' from Relude" 2751 | note: "'WrappedMonoid' is already exported from Relude" 2752 | rhs: WrappedMonoid 2753 | - warn: 2754 | lhs: Data.Semigroup.cycle1 2755 | name: "Use 'cycle1' from Relude" 2756 | note: "'cycle1' is already exported from Relude" 2757 | rhs: cycle1 2758 | - warn: 2759 | lhs: Data.Semigroup.mtimesDefault 2760 | name: "Use 'mtimesDefault' from Relude" 2761 | note: "'mtimesDefault' is already exported from Relude" 2762 | rhs: mtimesDefault 2763 | - warn: 2764 | lhs: Data.Semigroup.stimesIdempotent 2765 | name: "Use 'stimesIdempotent' from Relude" 2766 | note: "'stimesIdempotent' is already exported from Relude" 2767 | rhs: stimesIdempotent 2768 | - warn: 2769 | lhs: Data.Semigroup.stimesIdempotentMonoid 2770 | name: "Use 'stimesIdempotentMonoid' from Relude" 2771 | note: "'stimesIdempotentMonoid' is already exported from Relude" 2772 | rhs: stimesIdempotentMonoid 2773 | - warn: 2774 | lhs: Data.Semigroup.stimesMonoid 2775 | name: "Use 'stimesMonoid' from Relude" 2776 | note: "'stimesMonoid' is already exported from Relude" 2777 | rhs: stimesMonoid 2778 | - warn: 2779 | lhs: Data.ByteString.ByteString 2780 | name: "Use 'ByteString' from Relude" 2781 | note: "'ByteString' is already exported from Relude" 2782 | rhs: ByteString 2783 | - warn: 2784 | lhs: Data.ByteString.Short.ShortByteString 2785 | name: "Use 'ShortByteString' from Relude" 2786 | note: "'ShortByteString' is already exported from Relude" 2787 | rhs: ShortByteString 2788 | - warn: 2789 | lhs: Data.ByteString.Short.toShort 2790 | name: "Use 'toShort' from Relude" 2791 | note: "'toShort' is already exported from Relude" 2792 | rhs: toShort 2793 | - warn: 2794 | lhs: Data.ByteString.Short.fromShort 2795 | name: "Use 'fromShort' from Relude" 2796 | note: "'fromShort' is already exported from Relude" 2797 | rhs: fromShort 2798 | - warn: 2799 | lhs: Data.String.IsString 2800 | name: "Use 'IsString' from Relude" 2801 | note: "'IsString' is already exported from Relude" 2802 | rhs: IsString 2803 | - warn: 2804 | lhs: Data.String.fromString 2805 | name: "Use 'fromString' from Relude" 2806 | note: "'fromString' is already exported from Relude" 2807 | rhs: fromString 2808 | - warn: 2809 | lhs: Data.Text.Text 2810 | name: "Use 'Text' from Relude" 2811 | note: "'Text' is already exported from Relude" 2812 | rhs: Text 2813 | - warn: 2814 | lhs: Data.Text.lines 2815 | name: "Use 'lines' from Relude" 2816 | note: "'lines' is already exported from Relude" 2817 | rhs: lines 2818 | - warn: 2819 | lhs: Data.Text.unlines 2820 | name: "Use 'unlines' from Relude" 2821 | note: "'unlines' is already exported from Relude" 2822 | rhs: unlines 2823 | - warn: 2824 | lhs: Data.Text.words 2825 | name: "Use 'words' from Relude" 2826 | note: "'words' is already exported from Relude" 2827 | rhs: words 2828 | - warn: 2829 | lhs: Data.Text.unwords 2830 | name: "Use 'unwords' from Relude" 2831 | note: "'unwords' is already exported from Relude" 2832 | rhs: unwords 2833 | - warn: 2834 | lhs: "Data.Text.Encoding.decodeUtf8'" 2835 | name: "Use 'decodeUtf8'' from Relude" 2836 | note: "'decodeUtf8'' is already exported from Relude" 2837 | rhs: "decodeUtf8'" 2838 | - warn: 2839 | lhs: Data.Text.Encoding.decodeUtf8With 2840 | name: "Use 'decodeUtf8With' from Relude" 2841 | note: "'decodeUtf8With' is already exported from Relude" 2842 | rhs: decodeUtf8With 2843 | - warn: 2844 | lhs: Data.Text.Encoding.Error.OnDecodeError 2845 | name: "Use 'OnDecodeError' from Relude" 2846 | note: "'OnDecodeError' is already exported from Relude" 2847 | rhs: OnDecodeError 2848 | - warn: 2849 | lhs: Data.Text.Encoding.Error.OnError 2850 | name: "Use 'OnError' from Relude" 2851 | note: "'OnError' is already exported from Relude" 2852 | rhs: OnError 2853 | - warn: 2854 | lhs: Data.Text.Encoding.Error.UnicodeException 2855 | name: "Use 'UnicodeException' from Relude" 2856 | note: "'UnicodeException' is already exported from Relude" 2857 | rhs: UnicodeException 2858 | - warn: 2859 | lhs: Data.Text.Encoding.Error.lenientDecode 2860 | name: "Use 'lenientDecode' from Relude" 2861 | note: "'lenientDecode' is already exported from Relude" 2862 | rhs: lenientDecode 2863 | - warn: 2864 | lhs: Data.Text.Encoding.Error.strictDecode 2865 | name: "Use 'strictDecode' from Relude" 2866 | note: "'strictDecode' is already exported from Relude" 2867 | rhs: strictDecode 2868 | - warn: 2869 | lhs: Text.Read.Read 2870 | name: "Use 'Read' from Relude" 2871 | note: "'Read' is already exported from Relude" 2872 | rhs: Read 2873 | - warn: 2874 | lhs: Text.Read.readMaybe 2875 | name: "Use 'readMaybe' from Relude" 2876 | note: "'readMaybe' is already exported from Relude" 2877 | rhs: readMaybe 2878 | - warn: 2879 | lhs: "(liftIO (newEmptyMVar ))" 2880 | name: "'liftIO' is not needed" 2881 | note: "If you import 'newEmptyMVar' from Relude, it's already lifted" 2882 | rhs: newEmptyMVar 2883 | - warn: 2884 | lhs: "(liftIO (newMVar x))" 2885 | name: "'liftIO' is not needed" 2886 | note: "If you import 'newMVar' from Relude, it's already lifted" 2887 | rhs: newMVar 2888 | - warn: 2889 | lhs: "(liftIO (putMVar x y))" 2890 | name: "'liftIO' is not needed" 2891 | note: "If you import 'putMVar' from Relude, it's already lifted" 2892 | rhs: putMVar 2893 | - warn: 2894 | lhs: "(liftIO (readMVar x))" 2895 | name: "'liftIO' is not needed" 2896 | note: "If you import 'readMVar' from Relude, it's already lifted" 2897 | rhs: readMVar 2898 | - warn: 2899 | lhs: "(liftIO (swapMVar x y))" 2900 | name: "'liftIO' is not needed" 2901 | note: "If you import 'swapMVar' from Relude, it's already lifted" 2902 | rhs: swapMVar 2903 | - warn: 2904 | lhs: "(liftIO (takeMVar x))" 2905 | name: "'liftIO' is not needed" 2906 | note: "If you import 'takeMVar' from Relude, it's already lifted" 2907 | rhs: takeMVar 2908 | - warn: 2909 | lhs: "(liftIO (tryPutMVar x y))" 2910 | name: "'liftIO' is not needed" 2911 | note: "If you import 'tryPutMVar' from Relude, it's already lifted" 2912 | rhs: tryPutMVar 2913 | - warn: 2914 | lhs: "(liftIO (tryReadMVar x))" 2915 | name: "'liftIO' is not needed" 2916 | note: "If you import 'tryReadMVar' from Relude, it's already lifted" 2917 | rhs: tryReadMVar 2918 | - warn: 2919 | lhs: "(liftIO (tryTakeMVar x))" 2920 | name: "'liftIO' is not needed" 2921 | note: "If you import 'tryTakeMVar' from Relude, it's already lifted" 2922 | rhs: tryTakeMVar 2923 | - warn: 2924 | lhs: "(liftIO (atomically x))" 2925 | name: "'liftIO' is not needed" 2926 | note: "If you import 'atomically' from Relude, it's already lifted" 2927 | rhs: atomically 2928 | - warn: 2929 | lhs: "(liftIO (newTVarIO x))" 2930 | name: "'liftIO' is not needed" 2931 | note: "If you import 'newTVarIO' from Relude, it's already lifted" 2932 | rhs: newTVarIO 2933 | - warn: 2934 | lhs: "(liftIO (readTVarIO x))" 2935 | name: "'liftIO' is not needed" 2936 | note: "If you import 'readTVarIO' from Relude, it's already lifted" 2937 | rhs: readTVarIO 2938 | - warn: 2939 | lhs: "(liftIO (newTMVarIO x))" 2940 | name: "'liftIO' is not needed" 2941 | note: "If you import 'newTMVarIO' from Relude, it's already lifted" 2942 | rhs: newTMVarIO 2943 | - warn: 2944 | lhs: "(liftIO (newEmptyTMVarIO ))" 2945 | name: "'liftIO' is not needed" 2946 | note: "If you import 'newEmptyTMVarIO' from Relude, it's already lifted" 2947 | rhs: newEmptyTMVarIO 2948 | - warn: 2949 | lhs: "(liftIO (exitWith x))" 2950 | name: "'liftIO' is not needed" 2951 | note: "If you import 'exitWith' from Relude, it's already lifted" 2952 | rhs: exitWith 2953 | - warn: 2954 | lhs: "(liftIO (exitFailure ))" 2955 | name: "'liftIO' is not needed" 2956 | note: "If you import 'exitFailure' from Relude, it's already lifted" 2957 | rhs: exitFailure 2958 | - warn: 2959 | lhs: "(liftIO (exitSuccess ))" 2960 | name: "'liftIO' is not needed" 2961 | note: "If you import 'exitSuccess' from Relude, it's already lifted" 2962 | rhs: exitSuccess 2963 | - warn: 2964 | lhs: "(liftIO (die x))" 2965 | name: "'liftIO' is not needed" 2966 | note: "If you import 'die' from Relude, it's already lifted" 2967 | rhs: die 2968 | - warn: 2969 | lhs: "(liftIO (readFile x))" 2970 | name: "'liftIO' is not needed" 2971 | note: "If you import 'readFile' from Relude, it's already lifted" 2972 | rhs: readFile 2973 | - warn: 2974 | lhs: "(liftIO (writeFile x y))" 2975 | name: "'liftIO' is not needed" 2976 | note: "If you import 'writeFile' from Relude, it's already lifted" 2977 | rhs: writeFile 2978 | - warn: 2979 | lhs: "(liftIO (appendFile x y))" 2980 | name: "'liftIO' is not needed" 2981 | note: "If you import 'appendFile' from Relude, it's already lifted" 2982 | rhs: appendFile 2983 | - warn: 2984 | lhs: "(liftIO (readFileText x))" 2985 | name: "'liftIO' is not needed" 2986 | note: "If you import 'readFileText' from Relude, it's already lifted" 2987 | rhs: readFileText 2988 | - warn: 2989 | lhs: "(liftIO (writeFileText x y))" 2990 | name: "'liftIO' is not needed" 2991 | note: "If you import 'writeFileText' from Relude, it's already lifted" 2992 | rhs: writeFileText 2993 | - warn: 2994 | lhs: "(liftIO (appendFileText x y))" 2995 | name: "'liftIO' is not needed" 2996 | note: "If you import 'appendFileText' from Relude, it's already lifted" 2997 | rhs: appendFileText 2998 | - warn: 2999 | lhs: "(liftIO (readFileLText x))" 3000 | name: "'liftIO' is not needed" 3001 | note: "If you import 'readFileLText' from Relude, it's already lifted" 3002 | rhs: readFileLText 3003 | - warn: 3004 | lhs: "(liftIO (writeFileLText x y))" 3005 | name: "'liftIO' is not needed" 3006 | note: "If you import 'writeFileLText' from Relude, it's already lifted" 3007 | rhs: writeFileLText 3008 | - warn: 3009 | lhs: "(liftIO (appendFileLText x y))" 3010 | name: "'liftIO' is not needed" 3011 | note: "If you import 'appendFileLText' from Relude, it's already lifted" 3012 | rhs: appendFileLText 3013 | - warn: 3014 | lhs: "(liftIO (readFileBS x))" 3015 | name: "'liftIO' is not needed" 3016 | note: "If you import 'readFileBS' from Relude, it's already lifted" 3017 | rhs: readFileBS 3018 | - warn: 3019 | lhs: "(liftIO (writeFileBS x y))" 3020 | name: "'liftIO' is not needed" 3021 | note: "If you import 'writeFileBS' from Relude, it's already lifted" 3022 | rhs: writeFileBS 3023 | - warn: 3024 | lhs: "(liftIO (appendFileBS x y))" 3025 | name: "'liftIO' is not needed" 3026 | note: "If you import 'appendFileBS' from Relude, it's already lifted" 3027 | rhs: appendFileBS 3028 | - warn: 3029 | lhs: "(liftIO (readFileLBS x))" 3030 | name: "'liftIO' is not needed" 3031 | note: "If you import 'readFileLBS' from Relude, it's already lifted" 3032 | rhs: readFileLBS 3033 | - warn: 3034 | lhs: "(liftIO (writeFileLBS x y))" 3035 | name: "'liftIO' is not needed" 3036 | note: "If you import 'writeFileLBS' from Relude, it's already lifted" 3037 | rhs: writeFileLBS 3038 | - warn: 3039 | lhs: "(liftIO (appendFileLBS x y))" 3040 | name: "'liftIO' is not needed" 3041 | note: "If you import 'appendFileLBS' from Relude, it's already lifted" 3042 | rhs: appendFileLBS 3043 | - warn: 3044 | lhs: "(liftIO (newIORef x))" 3045 | name: "'liftIO' is not needed" 3046 | note: "If you import 'newIORef' from Relude, it's already lifted" 3047 | rhs: newIORef 3048 | - warn: 3049 | lhs: "(liftIO (readIORef x))" 3050 | name: "'liftIO' is not needed" 3051 | note: "If you import 'readIORef' from Relude, it's already lifted" 3052 | rhs: readIORef 3053 | - warn: 3054 | lhs: "(liftIO (writeIORef x y))" 3055 | name: "'liftIO' is not needed" 3056 | note: "If you import 'writeIORef' from Relude, it's already lifted" 3057 | rhs: writeIORef 3058 | - warn: 3059 | lhs: "(liftIO (modifyIORef x y))" 3060 | name: "'liftIO' is not needed" 3061 | note: "If you import 'modifyIORef' from Relude, it's already lifted" 3062 | rhs: modifyIORef 3063 | - warn: 3064 | lhs: "(liftIO (modifyIORef' x y))" 3065 | name: "'liftIO' is not needed" 3066 | note: "If you import 'modifyIORef'' from Relude, it's already lifted" 3067 | rhs: "modifyIORef'" 3068 | - warn: 3069 | lhs: "(liftIO (atomicModifyIORef x y))" 3070 | name: "'liftIO' is not needed" 3071 | note: "If you import 'atomicModifyIORef' from Relude, it's already lifted" 3072 | rhs: atomicModifyIORef 3073 | - warn: 3074 | lhs: "(liftIO (atomicModifyIORef' x y))" 3075 | name: "'liftIO' is not needed" 3076 | note: "If you import 'atomicModifyIORef'' from Relude, it's already lifted" 3077 | rhs: "atomicModifyIORef'" 3078 | - warn: 3079 | lhs: "(liftIO (atomicWriteIORef x y))" 3080 | name: "'liftIO' is not needed" 3081 | note: "If you import 'atomicWriteIORef' from Relude, it's already lifted" 3082 | rhs: atomicWriteIORef 3083 | - warn: 3084 | lhs: "(liftIO (getLine ))" 3085 | name: "'liftIO' is not needed" 3086 | note: "If you import 'getLine' from Relude, it's already lifted" 3087 | rhs: getLine 3088 | - warn: 3089 | lhs: "(liftIO (print x))" 3090 | name: "'liftIO' is not needed" 3091 | note: "If you import 'print' from Relude, it's already lifted" 3092 | rhs: print 3093 | - warn: 3094 | lhs: "(liftIO (putStr x))" 3095 | name: "'liftIO' is not needed" 3096 | note: "If you import 'putStr' from Relude, it's already lifted" 3097 | rhs: putStr 3098 | - warn: 3099 | lhs: "(liftIO (putStrLn x))" 3100 | name: "'liftIO' is not needed" 3101 | note: "If you import 'putStrLn' from Relude, it's already lifted" 3102 | rhs: putStrLn 3103 | - warn: 3104 | lhs: "(liftIO (putText x))" 3105 | name: "'liftIO' is not needed" 3106 | note: "If you import 'putText' from Relude, it's already lifted" 3107 | rhs: putText 3108 | - warn: 3109 | lhs: "(liftIO (putTextLn x))" 3110 | name: "'liftIO' is not needed" 3111 | note: "If you import 'putTextLn' from Relude, it's already lifted" 3112 | rhs: putTextLn 3113 | - warn: 3114 | lhs: "(liftIO (putLText x))" 3115 | name: "'liftIO' is not needed" 3116 | note: "If you import 'putLText' from Relude, it's already lifted" 3117 | rhs: putLText 3118 | - warn: 3119 | lhs: "(liftIO (putLTextLn x))" 3120 | name: "'liftIO' is not needed" 3121 | note: "If you import 'putLTextLn' from Relude, it's already lifted" 3122 | rhs: putLTextLn 3123 | - warn: 3124 | lhs: "(liftIO (putBS x))" 3125 | name: "'liftIO' is not needed" 3126 | note: "If you import 'putBS' from Relude, it's already lifted" 3127 | rhs: putBS 3128 | - warn: 3129 | lhs: "(liftIO (putBSLn x))" 3130 | name: "'liftIO' is not needed" 3131 | note: "If you import 'putBSLn' from Relude, it's already lifted" 3132 | rhs: putBSLn 3133 | - warn: 3134 | lhs: "(liftIO (putLBS x))" 3135 | name: "'liftIO' is not needed" 3136 | note: "If you import 'putLBS' from Relude, it's already lifted" 3137 | rhs: putLBS 3138 | - warn: 3139 | lhs: "(liftIO (putLBSLn x))" 3140 | name: "'liftIO' is not needed" 3141 | note: "If you import 'putLBSLn' from Relude, it's already lifted" 3142 | rhs: putLBSLn 3143 | - warn: 3144 | lhs: "(liftIO (hFlush x))" 3145 | name: "'liftIO' is not needed" 3146 | note: "If you import 'hFlush' from Relude, it's already lifted" 3147 | rhs: hFlush 3148 | - warn: 3149 | lhs: "(liftIO (hIsEOF x))" 3150 | name: "'liftIO' is not needed" 3151 | note: "If you import 'hIsEOF' from Relude, it's already lifted" 3152 | rhs: hIsEOF 3153 | - warn: 3154 | lhs: "(liftIO (hSetBuffering x y))" 3155 | name: "'liftIO' is not needed" 3156 | note: "If you import 'hSetBuffering' from Relude, it's already lifted" 3157 | rhs: hSetBuffering 3158 | - warn: 3159 | lhs: "(liftIO (hGetBuffering x))" 3160 | name: "'liftIO' is not needed" 3161 | note: "If you import 'hGetBuffering' from Relude, it's already lifted" 3162 | rhs: hGetBuffering 3163 | - warn: 3164 | lhs: "(liftIO (getArgs ))" 3165 | name: "'liftIO' is not needed" 3166 | note: "If you import 'getArgs' from Relude, it's already lifted" 3167 | rhs: getArgs 3168 | - warn: 3169 | lhs: "(liftIO (lookupEnv x))" 3170 | name: "'liftIO' is not needed" 3171 | note: "If you import 'lookupEnv' from Relude, it's already lifted" 3172 | rhs: lookupEnv 3173 | - hint: 3174 | lhs: "fmap (bimap f g)" 3175 | note: "Use `bimapF` from `Relude.Extra.Bifunctor`" 3176 | rhs: bimapF f g 3177 | - hint: 3178 | lhs: "bimap f g <$> x" 3179 | note: "Use `bimapF` from `Relude.Extra.Bifunctor`" 3180 | rhs: bimapF f g x 3181 | - hint: 3182 | lhs: "fmap (first f)" 3183 | note: "Use `firstF` from `Relude.Extra.Bifunctor`" 3184 | rhs: firstF f 3185 | - hint: 3186 | lhs: fmap . first 3187 | note: "Use `firstF` from `Relude.Extra.Bifunctor`" 3188 | rhs: firstF 3189 | - hint: 3190 | lhs: "fmap (second f)" 3191 | note: "Use `secondF` from `Relude.Extra.Bifunctor`" 3192 | rhs: secondF f 3193 | - hint: 3194 | lhs: fmap . second 3195 | note: "Use `secondF` from `Relude.Extra.Bifunctor`" 3196 | rhs: secondF 3197 | - hint: 3198 | lhs: "[minBound .. maxBound]" 3199 | note: "Use `universe` from `Relude.Extra.Enum`" 3200 | rhs: universe 3201 | - hint: 3202 | lhs: succ 3203 | note: "`succ` from `Prelude` is a pure function but it may throw exception. Consider using `next` from `Relude.Extra.Enum` instead." 3204 | rhs: next 3205 | - hint: 3206 | lhs: pred 3207 | note: "`pred` from `Prelude` is a pure function but it may throw exception. Consider using `prev` from `Relude.Extra.Enum` instead." 3208 | rhs: prev 3209 | - hint: 3210 | lhs: toEnum 3211 | note: "`toEnum` from `Prelude` is a pure function but it may throw exception. Consider using `safeToEnum` from `Relude.Extra.Enum` instead." 3212 | rhs: safeToEnum 3213 | - hint: 3214 | lhs: sum xs / length xs 3215 | note: "Use `average` from `Relude.Extra.Foldable`" 3216 | rhs: average xs 3217 | - hint: 3218 | lhs: "\\a -> (a, a)" 3219 | note: "Use `dup` from `Relude.Extra.Tuple`" 3220 | rhs: dup 3221 | - hint: 3222 | lhs: "\\a -> (f a, a)" 3223 | note: "Use `toFst` from `Relude.Extra.Tuple`" 3224 | rhs: toFst f 3225 | - hint: 3226 | lhs: "\\a -> (a, f a)" 3227 | note: "Use `toSnd` from `Relude.Extra.Tuple`" 3228 | rhs: toSnd f 3229 | - hint: 3230 | lhs: fmap . toFst 3231 | note: "Use `fmapToFst` from `Relude.Extra.Tuple`" 3232 | rhs: fmapToFst 3233 | - hint: 3234 | lhs: "fmap (toFst f)" 3235 | note: "Use `fmapToFst` from `Relude.Extra.Tuple`" 3236 | rhs: fmapToFst f 3237 | - hint: 3238 | lhs: fmap . toSnd 3239 | note: "Use `fmapToSnd` from `Relude.Extra.Tuple`" 3240 | rhs: fmapToSnd 3241 | - hint: 3242 | lhs: "fmap (toSnd f)" 3243 | note: "Use `fmapToSnd` from `Relude.Extra.Tuple`" 3244 | rhs: fmapToSnd f 3245 | - hint: 3246 | lhs: map . toFst 3247 | note: "Use `fmapToFst` from `Relude.Extra.Tuple`" 3248 | rhs: fmapToFst 3249 | - hint: 3250 | lhs: "map (toFst f)" 3251 | note: "Use `fmapToFst` from `Relude.Extra.Tuple`" 3252 | rhs: fmapToFst f 3253 | - hint: 3254 | lhs: map . toSnd 3255 | note: "Use `fmapToSnd` from `Relude.Extra.Tuple`" 3256 | rhs: fmapToSnd 3257 | - hint: 3258 | lhs: "map (toSnd f)" 3259 | note: "Use `fmapToSnd` from `Relude.Extra.Tuple`" 3260 | rhs: fmapToSnd f 3261 | - hint: 3262 | lhs: "fmap (,a) (f a)" 3263 | note: "Use `traverseToFst` from `Relude.Extra.Tuple`" 3264 | rhs: traverseToFst f a 3265 | - hint: 3266 | lhs: "fmap (flip (,) a) (f a)" 3267 | note: "Use `traverseToFst` from `Relude.Extra.Tuple`" 3268 | rhs: traverseToFst f a 3269 | - hint: 3270 | lhs: "(,a) <$> f a" 3271 | note: "Use `traverseToFst` from `Relude.Extra.Tuple`" 3272 | rhs: traverseToFst f a 3273 | - hint: 3274 | lhs: "flip (,) a <$> f a" 3275 | note: "Use `traverseToFst` from `Relude.Extra.Tuple`" 3276 | rhs: traverseToFst f a 3277 | - hint: 3278 | lhs: "fmap (a,) (f a)" 3279 | note: "Use `traverseToSnd` from `Relude.Extra.Tuple`" 3280 | rhs: traverseToSnd f a 3281 | - hint: 3282 | lhs: "fmap ((,) a) (f a)" 3283 | note: "Use `traverseToSnd` from `Relude.Extra.Tuple`" 3284 | rhs: traverseToSnd f a 3285 | - hint: 3286 | lhs: "(a,) <$> f a" 3287 | note: "Use `traverseToSnd` from `Relude.Extra.Tuple`" 3288 | rhs: traverseToSnd f a 3289 | - hint: 3290 | lhs: "(,) a <$> f a" 3291 | note: "Use `traverseToSnd` from `Relude.Extra.Tuple`" 3292 | rhs: traverseToSnd f a 3293 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "haskell.haskell", 6 | "bbenoist.nix", 7 | "jnoortheen.nix-ide", 8 | "mkhl.direnv" 9 | ] 10 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnType": true, 3 | "editor.formatOnSave": true, 4 | "nixEnvSelector.nixFile": "${workspaceRoot}/shell.nix", 5 | "haskell.formattingProvider": "fourmolu", 6 | "haskell.manageHLS": "PATH" 7 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU AFFERO GENERAL PUBLIC LICENSE 2 | Version 3, 19 November 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU Affero General Public License is a free, copyleft license for 11 | software and other kinds of works, specifically designed to ensure 12 | cooperation with the community in the case of network server software. 13 | 14 | The licenses for most software and other practical works are designed 15 | to take away your freedom to share and change the works. By contrast, 16 | our General Public Licenses are intended to guarantee your freedom to 17 | share and change all versions of a program--to make sure it remains free 18 | software for all its users. 19 | 20 | When we speak of free software, we are referring to freedom, not 21 | price. Our General Public Licenses are designed to make sure that you 22 | have the freedom to distribute copies of free software (and charge for 23 | them if you wish), that you receive source code or can get it if you 24 | want it, that you can change the software or use pieces of it in new 25 | free programs, and that you know you can do these things. 26 | 27 | Developers that use our General Public Licenses protect your rights 28 | with two steps: (1) assert copyright on the software, and (2) offer 29 | you this License which gives you legal permission to copy, distribute 30 | and/or modify the software. 31 | 32 | A secondary benefit of defending all users' freedom is that 33 | improvements made in alternate versions of the program, if they 34 | receive widespread use, become available for other developers to 35 | incorporate. Many developers of free software are heartened and 36 | encouraged by the resulting cooperation. However, in the case of 37 | software used on network servers, this result may fail to come about. 38 | The GNU General Public License permits making a modified version and 39 | letting the public access it on a server without ever releasing its 40 | source code to the public. 41 | 42 | The GNU Affero General Public License is designed specifically to 43 | ensure that, in such cases, the modified source code becomes available 44 | to the community. It requires the operator of a network server to 45 | provide the source code of the modified version running there to the 46 | users of that server. Therefore, public use of a modified version, on 47 | a publicly accessible server, gives the public access to the source 48 | code of the modified version. 49 | 50 | An older license, called the Affero General Public License and 51 | published by Affero, was designed to accomplish similar goals. This is 52 | a different license, not a version of the Affero GPL, but Affero has 53 | released a new version of the Affero GPL which permits relicensing under 54 | this license. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | TERMS AND CONDITIONS 60 | 61 | 0. Definitions. 62 | 63 | "This License" refers to version 3 of the GNU Affero General Public License. 64 | 65 | "Copyright" also means copyright-like laws that apply to other kinds of 66 | works, such as semiconductor masks. 67 | 68 | "The Program" refers to any copyrightable work licensed under this 69 | License. Each licensee is addressed as "you". "Licensees" and 70 | "recipients" may be individuals or organizations. 71 | 72 | To "modify" a work means to copy from or adapt all or part of the work 73 | in a fashion requiring copyright permission, other than the making of an 74 | exact copy. The resulting work is called a "modified version" of the 75 | earlier work or a work "based on" the earlier work. 76 | 77 | A "covered work" means either the unmodified Program or a work based 78 | on the Program. 79 | 80 | To "propagate" a work means to do anything with it that, without 81 | permission, would make you directly or secondarily liable for 82 | infringement under applicable copyright law, except executing it on a 83 | computer or modifying a private copy. Propagation includes copying, 84 | distribution (with or without modification), making available to the 85 | public, and in some countries other activities as well. 86 | 87 | To "convey" a work means any kind of propagation that enables other 88 | parties to make or receive copies. Mere interaction with a user through 89 | a computer network, with no transfer of a copy, is not conveying. 90 | 91 | An interactive user interface displays "Appropriate Legal Notices" 92 | to the extent that it includes a convenient and prominently visible 93 | feature that (1) displays an appropriate copyright notice, and (2) 94 | tells the user that there is no warranty for the work (except to the 95 | extent that warranties are provided), that licensees may convey the 96 | work under this License, and how to view a copy of this License. If 97 | the interface presents a list of user commands or options, such as a 98 | menu, a prominent item in the list meets this criterion. 99 | 100 | 1. Source Code. 101 | 102 | The "source code" for a work means the preferred form of the work 103 | for making modifications to it. "Object code" means any non-source 104 | form of a work. 105 | 106 | A "Standard Interface" means an interface that either is an official 107 | standard defined by a recognized standards body, or, in the case of 108 | interfaces specified for a particular programming language, one that 109 | is widely used among developers working in that language. 110 | 111 | The "System Libraries" of an executable work include anything, other 112 | than the work as a whole, that (a) is included in the normal form of 113 | packaging a Major Component, but which is not part of that Major 114 | Component, and (b) serves only to enable use of the work with that 115 | Major Component, or to implement a Standard Interface for which an 116 | implementation is available to the public in source code form. A 117 | "Major Component", in this context, means a major essential component 118 | (kernel, window system, and so on) of the specific operating system 119 | (if any) on which the executable work runs, or a compiler used to 120 | produce the work, or an object code interpreter used to run it. 121 | 122 | The "Corresponding Source" for a work in object code form means all 123 | the source code needed to generate, install, and (for an executable 124 | work) run the object code and to modify the work, including scripts to 125 | control those activities. However, it does not include the work's 126 | System Libraries, or general-purpose tools or generally available free 127 | programs which are used unmodified in performing those activities but 128 | which are not part of the work. For example, Corresponding Source 129 | includes interface definition files associated with source files for 130 | the work, and the source code for shared libraries and dynamically 131 | linked subprograms that the work is specifically designed to require, 132 | such as by intimate data communication or control flow between those 133 | subprograms and other parts of the work. 134 | 135 | The Corresponding Source need not include anything that users 136 | can regenerate automatically from other parts of the Corresponding 137 | Source. 138 | 139 | The Corresponding Source for a work in source code form is that 140 | same work. 141 | 142 | 2. Basic Permissions. 143 | 144 | All rights granted under this License are granted for the term of 145 | copyright on the Program, and are irrevocable provided the stated 146 | conditions are met. This License explicitly affirms your unlimited 147 | permission to run the unmodified Program. The output from running a 148 | covered work is covered by this License only if the output, given its 149 | content, constitutes a covered work. This License acknowledges your 150 | rights of fair use or other equivalent, as provided by copyright law. 151 | 152 | You may make, run and propagate covered works that you do not 153 | convey, without conditions so long as your license otherwise remains 154 | in force. You may convey covered works to others for the sole purpose 155 | of having them make modifications exclusively for you, or provide you 156 | with facilities for running those works, provided that you comply with 157 | the terms of this License in conveying all material for which you do 158 | not control copyright. Those thus making or running the covered works 159 | for you must do so exclusively on your behalf, under your direction 160 | and control, on terms that prohibit them from making any copies of 161 | your copyrighted material outside their relationship with you. 162 | 163 | Conveying under any other circumstances is permitted solely under 164 | the conditions stated below. Sublicensing is not allowed; section 10 165 | makes it unnecessary. 166 | 167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 168 | 169 | No covered work shall be deemed part of an effective technological 170 | measure under any applicable law fulfilling obligations under article 171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 172 | similar laws prohibiting or restricting circumvention of such 173 | measures. 174 | 175 | When you convey a covered work, you waive any legal power to forbid 176 | circumvention of technological measures to the extent such circumvention 177 | is effected by exercising rights under this License with respect to 178 | the covered work, and you disclaim any intention to limit operation or 179 | modification of the work as a means of enforcing, against the work's 180 | users, your or third parties' legal rights to forbid circumvention of 181 | technological measures. 182 | 183 | 4. Conveying Verbatim Copies. 184 | 185 | You may convey verbatim copies of the Program's source code as you 186 | receive it, in any medium, provided that you conspicuously and 187 | appropriately publish on each copy an appropriate copyright notice; 188 | keep intact all notices stating that this License and any 189 | non-permissive terms added in accord with section 7 apply to the code; 190 | keep intact all notices of the absence of any warranty; and give all 191 | recipients a copy of this License along with the Program. 192 | 193 | You may charge any price or no price for each copy that you convey, 194 | and you may offer support or warranty protection for a fee. 195 | 196 | 5. Conveying Modified Source Versions. 197 | 198 | You may convey a work based on the Program, or the modifications to 199 | produce it from the Program, in the form of source code under the 200 | terms of section 4, provided that you also meet all of these conditions: 201 | 202 | a) The work must carry prominent notices stating that you modified 203 | it, and giving a relevant date. 204 | 205 | b) The work must carry prominent notices stating that it is 206 | released under this License and any conditions added under section 207 | 7. This requirement modifies the requirement in section 4 to 208 | "keep intact all notices". 209 | 210 | c) You must license the entire work, as a whole, under this 211 | License to anyone who comes into possession of a copy. This 212 | License will therefore apply, along with any applicable section 7 213 | additional terms, to the whole of the work, and all its parts, 214 | regardless of how they are packaged. This License gives no 215 | permission to license the work in any other way, but it does not 216 | invalidate such permission if you have separately received it. 217 | 218 | d) If the work has interactive user interfaces, each must display 219 | Appropriate Legal Notices; however, if the Program has interactive 220 | interfaces that do not display Appropriate Legal Notices, your 221 | work need not make them do so. 222 | 223 | A compilation of a covered work with other separate and independent 224 | works, which are not by their nature extensions of the covered work, 225 | and which are not combined with it such as to form a larger program, 226 | in or on a volume of a storage or distribution medium, is called an 227 | "aggregate" if the compilation and its resulting copyright are not 228 | used to limit the access or legal rights of the compilation's users 229 | beyond what the individual works permit. Inclusion of a covered work 230 | in an aggregate does not cause this License to apply to the other 231 | parts of the aggregate. 232 | 233 | 6. Conveying Non-Source Forms. 234 | 235 | You may convey a covered work in object code form under the terms 236 | of sections 4 and 5, provided that you also convey the 237 | machine-readable Corresponding Source under the terms of this License, 238 | in one of these ways: 239 | 240 | a) Convey the object code in, or embodied in, a physical product 241 | (including a physical distribution medium), accompanied by the 242 | Corresponding Source fixed on a durable physical medium 243 | customarily used for software interchange. 244 | 245 | b) Convey the object code in, or embodied in, a physical product 246 | (including a physical distribution medium), accompanied by a 247 | written offer, valid for at least three years and valid for as 248 | long as you offer spare parts or customer support for that product 249 | model, to give anyone who possesses the object code either (1) a 250 | copy of the Corresponding Source for all the software in the 251 | product that is covered by this License, on a durable physical 252 | medium customarily used for software interchange, for a price no 253 | more than your reasonable cost of physically performing this 254 | conveying of source, or (2) access to copy the 255 | Corresponding Source from a network server at no charge. 256 | 257 | c) Convey individual copies of the object code with a copy of the 258 | written offer to provide the Corresponding Source. This 259 | alternative is allowed only occasionally and noncommercially, and 260 | only if you received the object code with such an offer, in accord 261 | with subsection 6b. 262 | 263 | d) Convey the object code by offering access from a designated 264 | place (gratis or for a charge), and offer equivalent access to the 265 | Corresponding Source in the same way through the same place at no 266 | further charge. You need not require recipients to copy the 267 | Corresponding Source along with the object code. If the place to 268 | copy the object code is a network server, the Corresponding Source 269 | may be on a different server (operated by you or a third party) 270 | that supports equivalent copying facilities, provided you maintain 271 | clear directions next to the object code saying where to find the 272 | Corresponding Source. Regardless of what server hosts the 273 | Corresponding Source, you remain obligated to ensure that it is 274 | available for as long as needed to satisfy these requirements. 275 | 276 | e) Convey the object code using peer-to-peer transmission, provided 277 | you inform other peers where the object code and Corresponding 278 | Source of the work are being offered to the general public at no 279 | charge under subsection 6d. 280 | 281 | A separable portion of the object code, whose source code is excluded 282 | from the Corresponding Source as a System Library, need not be 283 | included in conveying the object code work. 284 | 285 | A "User Product" is either (1) a "consumer product", which means any 286 | tangible personal property which is normally used for personal, family, 287 | or household purposes, or (2) anything designed or sold for incorporation 288 | into a dwelling. In determining whether a product is a consumer product, 289 | doubtful cases shall be resolved in favor of coverage. For a particular 290 | product received by a particular user, "normally used" refers to a 291 | typical or common use of that class of product, regardless of the status 292 | of the particular user or of the way in which the particular user 293 | actually uses, or expects or is expected to use, the product. A product 294 | is a consumer product regardless of whether the product has substantial 295 | commercial, industrial or non-consumer uses, unless such uses represent 296 | the only significant mode of use of the product. 297 | 298 | "Installation Information" for a User Product means any methods, 299 | procedures, authorization keys, or other information required to install 300 | and execute modified versions of a covered work in that User Product from 301 | a modified version of its Corresponding Source. The information must 302 | suffice to ensure that the continued functioning of the modified object 303 | code is in no case prevented or interfered with solely because 304 | modification has been made. 305 | 306 | If you convey an object code work under this section in, or with, or 307 | specifically for use in, a User Product, and the conveying occurs as 308 | part of a transaction in which the right of possession and use of the 309 | User Product is transferred to the recipient in perpetuity or for a 310 | fixed term (regardless of how the transaction is characterized), the 311 | Corresponding Source conveyed under this section must be accompanied 312 | by the Installation Information. But this requirement does not apply 313 | if neither you nor any third party retains the ability to install 314 | modified object code on the User Product (for example, the work has 315 | been installed in ROM). 316 | 317 | The requirement to provide Installation Information does not include a 318 | requirement to continue to provide support service, warranty, or updates 319 | for a work that has been modified or installed by the recipient, or for 320 | the User Product in which it has been modified or installed. Access to a 321 | network may be denied when the modification itself materially and 322 | adversely affects the operation of the network or violates the rules and 323 | protocols for communication across the network. 324 | 325 | Corresponding Source conveyed, and Installation Information provided, 326 | in accord with this section must be in a format that is publicly 327 | documented (and with an implementation available to the public in 328 | source code form), and must require no special password or key for 329 | unpacking, reading or copying. 330 | 331 | 7. Additional Terms. 332 | 333 | "Additional permissions" are terms that supplement the terms of this 334 | License by making exceptions from one or more of its conditions. 335 | Additional permissions that are applicable to the entire Program shall 336 | be treated as though they were included in this License, to the extent 337 | that they are valid under applicable law. If additional permissions 338 | apply only to part of the Program, that part may be used separately 339 | under those permissions, but the entire Program remains governed by 340 | this License without regard to the additional permissions. 341 | 342 | When you convey a copy of a covered work, you may at your option 343 | remove any additional permissions from that copy, or from any part of 344 | it. (Additional permissions may be written to require their own 345 | removal in certain cases when you modify the work.) You may place 346 | additional permissions on material, added by you to a covered work, 347 | for which you have or can give appropriate copyright permission. 348 | 349 | Notwithstanding any other provision of this License, for material you 350 | add to a covered work, you may (if authorized by the copyright holders of 351 | that material) supplement the terms of this License with terms: 352 | 353 | a) Disclaiming warranty or limiting liability differently from the 354 | terms of sections 15 and 16 of this License; or 355 | 356 | b) Requiring preservation of specified reasonable legal notices or 357 | author attributions in that material or in the Appropriate Legal 358 | Notices displayed by works containing it; or 359 | 360 | c) Prohibiting misrepresentation of the origin of that material, or 361 | requiring that modified versions of such material be marked in 362 | reasonable ways as different from the original version; or 363 | 364 | d) Limiting the use for publicity purposes of names of licensors or 365 | authors of the material; or 366 | 367 | e) Declining to grant rights under trademark law for use of some 368 | trade names, trademarks, or service marks; or 369 | 370 | f) Requiring indemnification of licensors and authors of that 371 | material by anyone who conveys the material (or modified versions of 372 | it) with contractual assumptions of liability to the recipient, for 373 | any liability that these contractual assumptions directly impose on 374 | those licensors and authors. 375 | 376 | All other non-permissive additional terms are considered "further 377 | restrictions" within the meaning of section 10. If the Program as you 378 | received it, or any part of it, contains a notice stating that it is 379 | governed by this License along with a term that is a further 380 | restriction, you may remove that term. If a license document contains 381 | a further restriction but permits relicensing or conveying under this 382 | License, you may add to a covered work material governed by the terms 383 | of that license document, provided that the further restriction does 384 | not survive such relicensing or conveying. 385 | 386 | If you add terms to a covered work in accord with this section, you 387 | must place, in the relevant source files, a statement of the 388 | additional terms that apply to those files, or a notice indicating 389 | where to find the applicable terms. 390 | 391 | Additional terms, permissive or non-permissive, may be stated in the 392 | form of a separately written license, or stated as exceptions; 393 | the above requirements apply either way. 394 | 395 | 8. Termination. 396 | 397 | You may not propagate or modify a covered work except as expressly 398 | provided under this License. Any attempt otherwise to propagate or 399 | modify it is void, and will automatically terminate your rights under 400 | this License (including any patent licenses granted under the third 401 | paragraph of section 11). 402 | 403 | However, if you cease all violation of this License, then your 404 | license from a particular copyright holder is reinstated (a) 405 | provisionally, unless and until the copyright holder explicitly and 406 | finally terminates your license, and (b) permanently, if the copyright 407 | holder fails to notify you of the violation by some reasonable means 408 | prior to 60 days after the cessation. 409 | 410 | Moreover, your license from a particular copyright holder is 411 | reinstated permanently if the copyright holder notifies you of the 412 | violation by some reasonable means, this is the first time you have 413 | received notice of violation of this License (for any work) from that 414 | copyright holder, and you cure the violation prior to 30 days after 415 | your receipt of the notice. 416 | 417 | Termination of your rights under this section does not terminate the 418 | licenses of parties who have received copies or rights from you under 419 | this License. If your rights have been terminated and not permanently 420 | reinstated, you do not qualify to receive new licenses for the same 421 | material under section 10. 422 | 423 | 9. Acceptance Not Required for Having Copies. 424 | 425 | You are not required to accept this License in order to receive or 426 | run a copy of the Program. Ancillary propagation of a covered work 427 | occurring solely as a consequence of using peer-to-peer transmission 428 | to receive a copy likewise does not require acceptance. However, 429 | nothing other than this License grants you permission to propagate or 430 | modify any covered work. These actions infringe copyright if you do 431 | not accept this License. Therefore, by modifying or propagating a 432 | covered work, you indicate your acceptance of this License to do so. 433 | 434 | 10. Automatic Licensing of Downstream Recipients. 435 | 436 | Each time you convey a covered work, the recipient automatically 437 | receives a license from the original licensors, to run, modify and 438 | propagate that work, subject to this License. You are not responsible 439 | for enforcing compliance by third parties with this License. 440 | 441 | An "entity transaction" is a transaction transferring control of an 442 | organization, or substantially all assets of one, or subdividing an 443 | organization, or merging organizations. If propagation of a covered 444 | work results from an entity transaction, each party to that 445 | transaction who receives a copy of the work also receives whatever 446 | licenses to the work the party's predecessor in interest had or could 447 | give under the previous paragraph, plus a right to possession of the 448 | Corresponding Source of the work from the predecessor in interest, if 449 | the predecessor has it or can get it with reasonable efforts. 450 | 451 | You may not impose any further restrictions on the exercise of the 452 | rights granted or affirmed under this License. For example, you may 453 | not impose a license fee, royalty, or other charge for exercise of 454 | rights granted under this License, and you may not initiate litigation 455 | (including a cross-claim or counterclaim in a lawsuit) alleging that 456 | any patent claim is infringed by making, using, selling, offering for 457 | sale, or importing the Program or any portion of it. 458 | 459 | 11. Patents. 460 | 461 | A "contributor" is a copyright holder who authorizes use under this 462 | License of the Program or a work on which the Program is based. The 463 | work thus licensed is called the contributor's "contributor version". 464 | 465 | A contributor's "essential patent claims" are all patent claims 466 | owned or controlled by the contributor, whether already acquired or 467 | hereafter acquired, that would be infringed by some manner, permitted 468 | by this License, of making, using, or selling its contributor version, 469 | but do not include claims that would be infringed only as a 470 | consequence of further modification of the contributor version. For 471 | purposes of this definition, "control" includes the right to grant 472 | patent sublicenses in a manner consistent with the requirements of 473 | this License. 474 | 475 | Each contributor grants you a non-exclusive, worldwide, royalty-free 476 | patent license under the contributor's essential patent claims, to 477 | make, use, sell, offer for sale, import and otherwise run, modify and 478 | propagate the contents of its contributor version. 479 | 480 | In the following three paragraphs, a "patent license" is any express 481 | agreement or commitment, however denominated, not to enforce a patent 482 | (such as an express permission to practice a patent or covenant not to 483 | sue for patent infringement). To "grant" such a patent license to a 484 | party means to make such an agreement or commitment not to enforce a 485 | patent against the party. 486 | 487 | If you convey a covered work, knowingly relying on a patent license, 488 | and the Corresponding Source of the work is not available for anyone 489 | to copy, free of charge and under the terms of this License, through a 490 | publicly available network server or other readily accessible means, 491 | then you must either (1) cause the Corresponding Source to be so 492 | available, or (2) arrange to deprive yourself of the benefit of the 493 | patent license for this particular work, or (3) arrange, in a manner 494 | consistent with the requirements of this License, to extend the patent 495 | license to downstream recipients. "Knowingly relying" means you have 496 | actual knowledge that, but for the patent license, your conveying the 497 | covered work in a country, or your recipient's use of the covered work 498 | in a country, would infringe one or more identifiable patents in that 499 | country that you have reason to believe are valid. 500 | 501 | If, pursuant to or in connection with a single transaction or 502 | arrangement, you convey, or propagate by procuring conveyance of, a 503 | covered work, and grant a patent license to some of the parties 504 | receiving the covered work authorizing them to use, propagate, modify 505 | or convey a specific copy of the covered work, then the patent license 506 | you grant is automatically extended to all recipients of the covered 507 | work and works based on it. 508 | 509 | A patent license is "discriminatory" if it does not include within 510 | the scope of its coverage, prohibits the exercise of, or is 511 | conditioned on the non-exercise of one or more of the rights that are 512 | specifically granted under this License. You may not convey a covered 513 | work if you are a party to an arrangement with a third party that is 514 | in the business of distributing software, under which you make payment 515 | to the third party based on the extent of your activity of conveying 516 | the work, and under which the third party grants, to any of the 517 | parties who would receive the covered work from you, a discriminatory 518 | patent license (a) in connection with copies of the covered work 519 | conveyed by you (or copies made from those copies), or (b) primarily 520 | for and in connection with specific products or compilations that 521 | contain the covered work, unless you entered into that arrangement, 522 | or that patent license was granted, prior to 28 March 2007. 523 | 524 | Nothing in this License shall be construed as excluding or limiting 525 | any implied license or other defenses to infringement that may 526 | otherwise be available to you under applicable patent law. 527 | 528 | 12. No Surrender of Others' Freedom. 529 | 530 | If conditions are imposed on you (whether by court order, agreement or 531 | otherwise) that contradict the conditions of this License, they do not 532 | excuse you from the conditions of this License. If you cannot convey a 533 | covered work so as to satisfy simultaneously your obligations under this 534 | License and any other pertinent obligations, then as a consequence you may 535 | not convey it at all. For example, if you agree to terms that obligate you 536 | to collect a royalty for further conveying from those to whom you convey 537 | the Program, the only way you could satisfy both those terms and this 538 | License would be to refrain entirely from conveying the Program. 539 | 540 | 13. Remote Network Interaction; Use with the GNU General Public License. 541 | 542 | Notwithstanding any other provision of this License, if you modify the 543 | Program, your modified version must prominently offer all users 544 | interacting with it remotely through a computer network (if your version 545 | supports such interaction) an opportunity to receive the Corresponding 546 | Source of your version by providing access to the Corresponding Source 547 | from a network server at no charge, through some standard or customary 548 | means of facilitating copying of software. This Corresponding Source 549 | shall include the Corresponding Source for any work covered by version 3 550 | of the GNU General Public License that is incorporated pursuant to the 551 | following paragraph. 552 | 553 | Notwithstanding any other provision of this License, you have 554 | permission to link or combine any covered work with a work licensed 555 | under version 3 of the GNU General Public License into a single 556 | combined work, and to convey the resulting work. The terms of this 557 | License will continue to apply to the part which is the covered work, 558 | but the work with which it is combined will remain governed by version 559 | 3 of the GNU General Public License. 560 | 561 | 14. Revised Versions of this License. 562 | 563 | The Free Software Foundation may publish revised and/or new versions of 564 | the GNU Affero General Public License from time to time. Such new versions 565 | will be similar in spirit to the present version, but may differ in detail to 566 | address new problems or concerns. 567 | 568 | Each version is given a distinguishing version number. If the 569 | Program specifies that a certain numbered version of the GNU Affero General 570 | Public License "or any later version" applies to it, you have the 571 | option of following the terms and conditions either of that numbered 572 | version or of any later version published by the Free Software 573 | Foundation. If the Program does not specify a version number of the 574 | GNU Affero General Public License, you may choose any version ever published 575 | by the Free Software Foundation. 576 | 577 | If the Program specifies that a proxy can decide which future 578 | versions of the GNU Affero General Public License can be used, that proxy's 579 | public statement of acceptance of a version permanently authorizes you 580 | to choose that version for the Program. 581 | 582 | Later license versions may give you additional or different 583 | permissions. However, no additional obligations are imposed on any 584 | author or copyright holder as a result of your choosing to follow a 585 | later version. 586 | 587 | 15. Disclaimer of Warranty. 588 | 589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 597 | 598 | 16. Limitation of Liability. 599 | 600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 608 | SUCH DAMAGES. 609 | 610 | 17. Interpretation of Sections 15 and 16. 611 | 612 | If the disclaimer of warranty and limitation of liability provided 613 | above cannot be given local legal effect according to their terms, 614 | reviewing courts shall apply local law that most closely approximates 615 | an absolute waiver of all civil liability in connection with the 616 | Program, unless a warranty or assumption of liability accompanies a 617 | copy of the Program in return for a fee. 618 | 619 | END OF TERMS AND CONDITIONS 620 | 621 | How to Apply These Terms to Your New Programs 622 | 623 | If you develop a new program, and you want it to be of the greatest 624 | possible use to the public, the best way to achieve this is to make it 625 | free software which everyone can redistribute and change under these terms. 626 | 627 | To do so, attach the following notices to the program. It is safest 628 | to attach them to the start of each source file to most effectively 629 | state the exclusion of warranty; and each file should have at least 630 | the "copyright" line and a pointer to where the full notice is found. 631 | 632 | 633 | Copyright (C) 634 | 635 | This program is free software: you can redistribute it and/or modify 636 | it under the terms of the GNU Affero General Public License as published 637 | by the Free Software Foundation, either version 3 of the License, or 638 | (at your option) any later version. 639 | 640 | This program is distributed in the hope that it will be useful, 641 | but WITHOUT ANY WARRANTY; without even the implied warranty of 642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 643 | GNU Affero General Public License for more details. 644 | 645 | You should have received a copy of the GNU Affero General Public License 646 | along with this program. If not, see . 647 | 648 | Also add information on how to contact you by electronic and paper mail. 649 | 650 | If your software can interact with users remotely through a computer 651 | network, you should also make sure that it provides a way for users to 652 | get its source. For example, if your program is a web application, its 653 | interface could display a "Source" link that leads users to an archive 654 | of the code. There are many ways you could offer source, and different 655 | solutions will be better for different programs; see section 13 for the 656 | specific requirements. 657 | 658 | You should also get your employer (if you work as a programmer) or school, 659 | if any, to sign a "copyright disclaimer" for the program, if necessary. 660 | For more information on this, and how to apply and follow the GNU AGPL, see 661 | . 662 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ema Template 2 | 3 | A very simple example [Ema](https://ema.srid.ca/) site that is based on Lucid2 & TailwindCSS 3. Use it to bootstrap your next static site using Ema. 4 | 5 | The generated HTML site can be previewed here: https://srid.github.io/ema-template/ 6 | 7 | ## Getting Started 8 | 9 | To develop with full IDE support in Visual Studio Code, follow these steps: 10 | 11 | - [Install Nix](https://nixos.asia/en/install) 12 | - And [setup direnv](https://nixos.asia/en/direnv) 13 | - Run `nix develop -i -c haskell-language-server` to sanity check your environment 14 | - Open the repository [as single-folder workspace](https://code.visualstudio.com/docs/editor/workspaces#_singlefolder-workspaces) in Visual Studio Code 15 | - Install the recommended extensions 16 | - Active the direnv environment 17 | - Press Ctrl+Shift+B in VSCode, or run `nix develop -c just run` in terminal (`just run` if direnv is already active), to launch the Ema dev server, and navigate to http://localhost:9001/ 18 | 19 | All but the final step need to be done only once. Check [the Ema tutorial](https://ema.srid.ca/tutorial) next. 20 | 21 | ## Note 22 | 23 | - This project uses [relude](https://github.com/kowainik/relude) as its prelude, as well as Tailwind+Lucid as CSS utility and HTML DSL. Even though the author highly recommends them, you are of course free to swap them out for the library of your choice. 24 | - Tailwind CSS is compiled, alongside Ghcid, via foreman (see `flake.nix`) 25 | - As a first step to using this template, rename your project using https://srid.ca/haskell-template/start#rename-the-project (use `ema-template` in place of `haskell-template`) 26 | - Configuration: 27 | - To change the port (or the Ema CLI arguments, used by `nix develop -c just run`), see `./.ghcid` (if you leave out `--port` a random port will be used) 28 | - To add/remove Haskell dependencies, see https://community.flake.parts/haskell-flake/dependency 29 | - To generate the site, run: 30 | ```sh 31 | nix build .#site 32 | # Alternatively: 33 | # > mkdir ../output 34 | # > nix run . -- --base-url=/ gen ../output 35 | ``` 36 | 37 | ## Non-Nix workflow 38 | 39 | To use this repository without Nix (such as with plain Cabal or Stack) you need to have the following installed manually: 40 | 41 | - ghcid 42 | - [tailwind runner](https://hackage.haskell.org/package/tailwind) along with [tailwind CLI](https://tailwindcss.com/docs/installation) 43 | - [foreman](http://ddollar.github.io/foreman/) (or one of its rewrites) 44 | - Add a `Procfile`; see flake.nix to determine what should go in its `Procfile` 45 | 46 | Once all the above are installed and setup, run `foreman start` to start the Ema live server. 47 | -------------------------------------------------------------------------------- /ema-template.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 2.4 2 | name: ema-template 3 | version: 0.1.0.0 4 | license: AGPL-3.0-only 5 | copyright: 2022 Sridhar Ratnakumar 6 | maintainer: srid@srid.ca 7 | author: Sridhar Ratnakumar 8 | category: Web 9 | 10 | -- A short (one-line) description of the package. 11 | -- synopsis: 12 | 13 | -- A longer description of the package. 14 | -- description: 15 | 16 | -- A URL where users can report bugs. 17 | -- bug-reports: 18 | 19 | extra-source-files: 20 | LICENSE 21 | README.md 22 | 23 | data-dir: static 24 | data-files: 25 | *.css 26 | *.svg 27 | 28 | executable ema-template 29 | build-depends: 30 | , aeson 31 | , async 32 | , base >=4 && <5 33 | , blaze-html 34 | , blaze-markup 35 | , containers 36 | , data-default 37 | , directory 38 | , ema >=0.10 39 | , ema-extra >=0.10 40 | , ema-generics >=0.10 41 | , filepath 42 | , generic-optics 43 | , lucid2 44 | , monad-logger 45 | , optics-core 46 | , optparse-applicative 47 | , relude >=1.0 48 | , text 49 | , time 50 | , unionmount >=0.2 51 | , unliftio 52 | 53 | mixins: 54 | base hiding (Prelude), 55 | relude (Relude as Prelude, Relude.Container.One), 56 | relude 57 | 58 | ghc-options: 59 | -Wall -Wincomplete-record-updates -Wincomplete-uni-patterns 60 | -Wmissing-deriving-strategies -Wunused-foralls -Wunused-foralls 61 | -fprint-explicit-foralls -fprint-explicit-kinds -threaded 62 | 63 | default-extensions: 64 | BangPatterns 65 | ConstraintKinds 66 | DataKinds 67 | DeriveAnyClass 68 | DeriveDataTypeable 69 | DeriveFoldable 70 | DeriveFunctor 71 | DeriveGeneric 72 | DeriveLift 73 | DeriveTraversable 74 | DerivingStrategies 75 | DerivingVia 76 | EmptyCase 77 | EmptyDataDecls 78 | EmptyDataDeriving 79 | ExistentialQuantification 80 | ExplicitForAll 81 | FlexibleContexts 82 | FlexibleInstances 83 | GADTSyntax 84 | GeneralisedNewtypeDeriving 85 | ImportQualifiedPost 86 | KindSignatures 87 | LambdaCase 88 | MultiParamTypeClasses 89 | MultiWayIf 90 | NoStarIsType 91 | NumericUnderscores 92 | OverloadedStrings 93 | PolyKinds 94 | PostfixOperators 95 | RankNTypes 96 | ScopedTypeVariables 97 | StandaloneDeriving 98 | StandaloneKindSignatures 99 | TupleSections 100 | TypeApplications 101 | TypeFamilies 102 | TypeOperators 103 | ViewPatterns 104 | 105 | main-is: Main.hs 106 | hs-source-dirs: src 107 | default-language: Haskell2010 108 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "commonmark-simple": { 4 | "flake": false, 5 | "locked": { 6 | "lastModified": 1705078713, 7 | "narHash": "sha256-YgDHJG8M47ZXGLWu8o7MhXbIrgQ0Ai32Gr8nKvZGGw8=", 8 | "owner": "srid", 9 | "repo": "commonmark-simple", 10 | "rev": "fc106c94f781f6a35ef66900880edc08cbe3b034", 11 | "type": "github" 12 | }, 13 | "original": { 14 | "owner": "srid", 15 | "repo": "commonmark-simple", 16 | "type": "github" 17 | } 18 | }, 19 | "commonmark-wikilink": { 20 | "flake": false, 21 | "locked": { 22 | "lastModified": 1705502834, 23 | "narHash": "sha256-79fzI4fPhCkfusDXctQwwmjIcWMrLfTvUtKBY32asuM=", 24 | "owner": "srid", 25 | "repo": "commonmark-wikilink", 26 | "rev": "f6d7bdf7f1fce09ba2a4259b0306b0eef24c0cf7", 27 | "type": "github" 28 | }, 29 | "original": { 30 | "owner": "srid", 31 | "repo": "commonmark-wikilink", 32 | "type": "github" 33 | } 34 | }, 35 | "ema": { 36 | "inputs": { 37 | "emanote": "emanote", 38 | "flake-parts": "flake-parts_2", 39 | "flake-root": "flake-root_2", 40 | "haskell-flake": "haskell-flake_2", 41 | "nixpkgs": [ 42 | "nixpkgs" 43 | ], 44 | "treefmt-nix": "treefmt-nix_2" 45 | }, 46 | "locked": { 47 | "lastModified": 1724260267, 48 | "narHash": "sha256-pxTlvpK0l7pek43FIz6KYAazK0BWbnuBJSFrcShVoWE=", 49 | "owner": "srid", 50 | "repo": "ema", 51 | "rev": "16e2752267cd49027e281409daa25b6ecba68fd3", 52 | "type": "github" 53 | }, 54 | "original": { 55 | "owner": "srid", 56 | "repo": "ema", 57 | "type": "github" 58 | } 59 | }, 60 | "ema_2": { 61 | "inputs": { 62 | "flake-parts": [ 63 | "ema", 64 | "emanote", 65 | "flake-parts" 66 | ], 67 | "flake-root": [ 68 | "ema", 69 | "emanote", 70 | "flake-root" 71 | ], 72 | "haskell-flake": [ 73 | "ema", 74 | "emanote", 75 | "haskell-flake" 76 | ], 77 | "nixpkgs": [ 78 | "ema", 79 | "emanote", 80 | "nixpkgs" 81 | ], 82 | "treefmt-nix": [ 83 | "ema", 84 | "emanote", 85 | "treefmt-nix" 86 | ] 87 | }, 88 | "locked": { 89 | "lastModified": 1707484760, 90 | "narHash": "sha256-2wHRjoFJUpVnH7H/80bnaw8h3WELZqP9dM6DfjXWtAo=", 91 | "owner": "srid", 92 | "repo": "ema", 93 | "rev": "e3539ddd27b72a6bb90c8614ae63c70ff3351936", 94 | "type": "github" 95 | }, 96 | "original": { 97 | "owner": "srid", 98 | "repo": "ema", 99 | "type": "github" 100 | } 101 | }, 102 | "emanote": { 103 | "inputs": { 104 | "commonmark-simple": "commonmark-simple", 105 | "commonmark-wikilink": "commonmark-wikilink", 106 | "ema": "ema_2", 107 | "emanote-template": "emanote-template", 108 | "flake-parts": "flake-parts", 109 | "flake-root": "flake-root", 110 | "haskell-flake": "haskell-flake", 111 | "heist-extra": "heist-extra", 112 | "nixpkgs": "nixpkgs", 113 | "systems": "systems", 114 | "treefmt-nix": "treefmt-nix", 115 | "unionmount": "unionmount" 116 | }, 117 | "locked": { 118 | "lastModified": 1709754457, 119 | "narHash": "sha256-JBpIQsCSaQzLY5LnCO9xj3O7nnv0ekgO1ZTSkevRfi4=", 120 | "owner": "srid", 121 | "repo": "emanote", 122 | "rev": "922f79430416b09e91d735a27b01ddbb48ef7b83", 123 | "type": "github" 124 | }, 125 | "original": { 126 | "owner": "srid", 127 | "repo": "emanote", 128 | "type": "github" 129 | } 130 | }, 131 | "emanote-template": { 132 | "flake": false, 133 | "locked": { 134 | "lastModified": 1703877265, 135 | "narHash": "sha256-2xdikzzHrIHr1s2pAJrBJU8mZP258Na3V4P4RWteDZM=", 136 | "owner": "srid", 137 | "repo": "emanote-template", 138 | "rev": "9d458b63c80162519ae55814e60f17cc9d3f95a3", 139 | "type": "github" 140 | }, 141 | "original": { 142 | "owner": "srid", 143 | "repo": "emanote-template", 144 | "type": "github" 145 | } 146 | }, 147 | "flake-parts": { 148 | "inputs": { 149 | "nixpkgs-lib": "nixpkgs-lib" 150 | }, 151 | "locked": { 152 | "lastModified": 1704982712, 153 | "narHash": "sha256-2Ptt+9h8dczgle2Oo6z5ni5rt/uLMG47UFTR1ry/wgg=", 154 | "owner": "hercules-ci", 155 | "repo": "flake-parts", 156 | "rev": "07f6395285469419cf9d078f59b5b49993198c00", 157 | "type": "github" 158 | }, 159 | "original": { 160 | "owner": "hercules-ci", 161 | "repo": "flake-parts", 162 | "type": "github" 163 | } 164 | }, 165 | "flake-parts_2": { 166 | "inputs": { 167 | "nixpkgs-lib": "nixpkgs-lib_2" 168 | }, 169 | "locked": { 170 | "lastModified": 1706830856, 171 | "narHash": "sha256-a0NYyp+h9hlb7ddVz4LUn1vT/PLwqfrWYcHMvFB1xYg=", 172 | "owner": "hercules-ci", 173 | "repo": "flake-parts", 174 | "rev": "b253292d9c0a5ead9bc98c4e9a26c6312e27d69f", 175 | "type": "github" 176 | }, 177 | "original": { 178 | "owner": "hercules-ci", 179 | "repo": "flake-parts", 180 | "type": "github" 181 | } 182 | }, 183 | "flake-parts_3": { 184 | "inputs": { 185 | "nixpkgs-lib": "nixpkgs-lib_3" 186 | }, 187 | "locked": { 188 | "lastModified": 1735774679, 189 | "narHash": "sha256-soePLBazJk0qQdDVhdbM98vYdssfs3WFedcq+raipRI=", 190 | "owner": "hercules-ci", 191 | "repo": "flake-parts", 192 | "rev": "f2f7418ce0ab4a5309a4596161d154cfc877af66", 193 | "type": "github" 194 | }, 195 | "original": { 196 | "owner": "hercules-ci", 197 | "repo": "flake-parts", 198 | "type": "github" 199 | } 200 | }, 201 | "flake-root": { 202 | "locked": { 203 | "lastModified": 1692742795, 204 | "narHash": "sha256-f+Y0YhVCIJ06LemO+3Xx00lIcqQxSKJHXT/yk1RTKxw=", 205 | "owner": "srid", 206 | "repo": "flake-root", 207 | "rev": "d9a70d9c7a5fd7f3258ccf48da9335e9b47c3937", 208 | "type": "github" 209 | }, 210 | "original": { 211 | "owner": "srid", 212 | "repo": "flake-root", 213 | "type": "github" 214 | } 215 | }, 216 | "flake-root_2": { 217 | "locked": { 218 | "lastModified": 1692742795, 219 | "narHash": "sha256-f+Y0YhVCIJ06LemO+3Xx00lIcqQxSKJHXT/yk1RTKxw=", 220 | "owner": "srid", 221 | "repo": "flake-root", 222 | "rev": "d9a70d9c7a5fd7f3258ccf48da9335e9b47c3937", 223 | "type": "github" 224 | }, 225 | "original": { 226 | "owner": "srid", 227 | "repo": "flake-root", 228 | "type": "github" 229 | } 230 | }, 231 | "fourmolu-nix": { 232 | "locked": { 233 | "lastModified": 1707266073, 234 | "narHash": "sha256-tCFzZQJicDdYjnuJiNK4hiiRAH7c2wQzMhOCdUMbVKE=", 235 | "owner": "jedimahdi", 236 | "repo": "fourmolu-nix", 237 | "rev": "717f5a91b0d7b97b1be7ecc3a0fd42d37ffe1c9b", 238 | "type": "github" 239 | }, 240 | "original": { 241 | "owner": "jedimahdi", 242 | "repo": "fourmolu-nix", 243 | "type": "github" 244 | } 245 | }, 246 | "git-hooks": { 247 | "flake": false, 248 | "locked": { 249 | "lastModified": 1735882644, 250 | "narHash": "sha256-3FZAG+pGt3OElQjesCAWeMkQ7C/nB1oTHLRQ8ceP110=", 251 | "owner": "cachix", 252 | "repo": "git-hooks.nix", 253 | "rev": "a5a961387e75ae44cc20f0a57ae463da5e959656", 254 | "type": "github" 255 | }, 256 | "original": { 257 | "owner": "cachix", 258 | "repo": "git-hooks.nix", 259 | "type": "github" 260 | } 261 | }, 262 | "haskell-flake": { 263 | "locked": { 264 | "lastModified": 1709233214, 265 | "narHash": "sha256-kraFY5MmY7yxsEtSF8qPrFVmA6MXkF+sJfo7EV1dcY8=", 266 | "owner": "srid", 267 | "repo": "haskell-flake", 268 | "rev": "3a8c1b58cff60886260156a20a3b3ad725bbf885", 269 | "type": "github" 270 | }, 271 | "original": { 272 | "owner": "srid", 273 | "repo": "haskell-flake", 274 | "type": "github" 275 | } 276 | }, 277 | "haskell-flake_2": { 278 | "locked": { 279 | "lastModified": 1707242163, 280 | "narHash": "sha256-w+cBynh7yqnpVtFdu1SEZxPgtlz/nWnv47D5crnPXHM=", 281 | "owner": "srid", 282 | "repo": "haskell-flake", 283 | "rev": "f9d17c3aa68e65529f424816c8b9346ae602d1de", 284 | "type": "github" 285 | }, 286 | "original": { 287 | "owner": "srid", 288 | "repo": "haskell-flake", 289 | "type": "github" 290 | } 291 | }, 292 | "haskell-flake_3": { 293 | "locked": { 294 | "lastModified": 1735436109, 295 | "narHash": "sha256-WIn6GVY+UiaCL+kUeF8cfPXE5kxF4UPcFGx62U3kmAE=", 296 | "owner": "srid", 297 | "repo": "haskell-flake", 298 | "rev": "207b1d67106a799df892b380ed9dc7578746fbc1", 299 | "type": "github" 300 | }, 301 | "original": { 302 | "owner": "srid", 303 | "repo": "haskell-flake", 304 | "type": "github" 305 | } 306 | }, 307 | "heist-extra": { 308 | "flake": false, 309 | "locked": { 310 | "lastModified": 1706086475, 311 | "narHash": "sha256-scXMVFKSaS4Wi4y6I84oPKHaTmLECsvq8eLxGL0XH5o=", 312 | "owner": "srid", 313 | "repo": "heist-extra", 314 | "rev": "c6d8ef79b415fab276fb461d5860bbf2628e6e43", 315 | "type": "github" 316 | }, 317 | "original": { 318 | "owner": "srid", 319 | "repo": "heist-extra", 320 | "type": "github" 321 | } 322 | }, 323 | "nixpkgs": { 324 | "locked": { 325 | "lastModified": 1704842529, 326 | "narHash": "sha256-OTeQA+F8d/Evad33JMfuXC89VMetQbsU4qcaePchGr4=", 327 | "owner": "nixos", 328 | "repo": "nixpkgs", 329 | "rev": "eabe8d3eface69f5bb16c18f8662a702f50c20d5", 330 | "type": "github" 331 | }, 332 | "original": { 333 | "owner": "nixos", 334 | "ref": "nixpkgs-unstable", 335 | "repo": "nixpkgs", 336 | "type": "github" 337 | } 338 | }, 339 | "nixpkgs-lib": { 340 | "locked": { 341 | "dir": "lib", 342 | "lastModified": 1703961334, 343 | "narHash": "sha256-M1mV/Cq+pgjk0rt6VxoyyD+O8cOUiai8t9Q6Yyq4noY=", 344 | "owner": "NixOS", 345 | "repo": "nixpkgs", 346 | "rev": "b0d36bd0a420ecee3bc916c91886caca87c894e9", 347 | "type": "github" 348 | }, 349 | "original": { 350 | "dir": "lib", 351 | "owner": "NixOS", 352 | "ref": "nixos-unstable", 353 | "repo": "nixpkgs", 354 | "type": "github" 355 | } 356 | }, 357 | "nixpkgs-lib_2": { 358 | "locked": { 359 | "dir": "lib", 360 | "lastModified": 1706550542, 361 | "narHash": "sha256-UcsnCG6wx++23yeER4Hg18CXWbgNpqNXcHIo5/1Y+hc=", 362 | "owner": "NixOS", 363 | "repo": "nixpkgs", 364 | "rev": "97b17f32362e475016f942bbdfda4a4a72a8a652", 365 | "type": "github" 366 | }, 367 | "original": { 368 | "dir": "lib", 369 | "owner": "NixOS", 370 | "ref": "nixos-unstable", 371 | "repo": "nixpkgs", 372 | "type": "github" 373 | } 374 | }, 375 | "nixpkgs-lib_3": { 376 | "locked": { 377 | "lastModified": 1735774519, 378 | "narHash": "sha256-CewEm1o2eVAnoqb6Ml+Qi9Gg/EfNAxbRx1lANGVyoLI=", 379 | "type": "tarball", 380 | "url": "https://github.com/NixOS/nixpkgs/archive/e9b51731911566bbf7e4895475a87fe06961de0b.tar.gz" 381 | }, 382 | "original": { 383 | "type": "tarball", 384 | "url": "https://github.com/NixOS/nixpkgs/archive/e9b51731911566bbf7e4895475a87fe06961de0b.tar.gz" 385 | } 386 | }, 387 | "nixpkgs_2": { 388 | "locked": { 389 | "lastModified": 1705856552, 390 | "narHash": "sha256-JXfnuEf5Yd6bhMs/uvM67/joxYKoysyE3M2k6T3eWbg=", 391 | "owner": "nixos", 392 | "repo": "nixpkgs", 393 | "rev": "612f97239e2cc474c13c9dafa0df378058c5ad8d", 394 | "type": "github" 395 | }, 396 | "original": { 397 | "owner": "nixos", 398 | "ref": "nixos-unstable", 399 | "repo": "nixpkgs", 400 | "type": "github" 401 | } 402 | }, 403 | "nixpkgs_3": { 404 | "locked": { 405 | "lastModified": 1735821806, 406 | "narHash": "sha256-cuNapx/uQeCgeuhUhdck3JKbgpsml259sjUQnWM7zW8=", 407 | "owner": "nixos", 408 | "repo": "nixpkgs", 409 | "rev": "d6973081434f88088e5321f83ebafe9a1167c367", 410 | "type": "github" 411 | }, 412 | "original": { 413 | "owner": "nixos", 414 | "ref": "nixpkgs-unstable", 415 | "repo": "nixpkgs", 416 | "type": "github" 417 | } 418 | }, 419 | "process-compose-flake": { 420 | "locked": { 421 | "lastModified": 1733325752, 422 | "narHash": "sha256-79tzPuXNRo1NUllafYW6SjeLtjqfnLGq7tHCM7cAXNg=", 423 | "owner": "Platonic-Systems", 424 | "repo": "process-compose-flake", 425 | "rev": "1012530b582f1bd3b102295c799358d95abf42d7", 426 | "type": "github" 427 | }, 428 | "original": { 429 | "owner": "Platonic-Systems", 430 | "repo": "process-compose-flake", 431 | "type": "github" 432 | } 433 | }, 434 | "root": { 435 | "inputs": { 436 | "ema": "ema", 437 | "flake-parts": "flake-parts_3", 438 | "fourmolu-nix": "fourmolu-nix", 439 | "git-hooks": "git-hooks", 440 | "haskell-flake": "haskell-flake_3", 441 | "nixpkgs": "nixpkgs_3", 442 | "process-compose-flake": "process-compose-flake", 443 | "systems": "systems_2" 444 | } 445 | }, 446 | "systems": { 447 | "locked": { 448 | "lastModified": 1681028828, 449 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 450 | "owner": "nix-systems", 451 | "repo": "default", 452 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 453 | "type": "github" 454 | }, 455 | "original": { 456 | "owner": "nix-systems", 457 | "repo": "default", 458 | "type": "github" 459 | } 460 | }, 461 | "systems_2": { 462 | "locked": { 463 | "lastModified": 1681028828, 464 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 465 | "owner": "nix-systems", 466 | "repo": "default", 467 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 468 | "type": "github" 469 | }, 470 | "original": { 471 | "owner": "nix-systems", 472 | "repo": "default", 473 | "type": "github" 474 | } 475 | }, 476 | "treefmt-nix": { 477 | "inputs": { 478 | "nixpkgs": [ 479 | "ema", 480 | "emanote", 481 | "nixpkgs" 482 | ] 483 | }, 484 | "locked": { 485 | "lastModified": 1693468138, 486 | "narHash": "sha256-DddblCahuTW8K0ncPOheTlG3igE8b15LJjafF1PWhOo=", 487 | "owner": "numtide", 488 | "repo": "treefmt-nix", 489 | "rev": "6930a5ba0a722385baf273885a03f561dcb1af67", 490 | "type": "github" 491 | }, 492 | "original": { 493 | "owner": "numtide", 494 | "repo": "treefmt-nix", 495 | "type": "github" 496 | } 497 | }, 498 | "treefmt-nix_2": { 499 | "inputs": { 500 | "nixpkgs": "nixpkgs_2" 501 | }, 502 | "locked": { 503 | "lastModified": 1707300477, 504 | "narHash": "sha256-qQF0fEkHlnxHcrKIMRzOETnRBksUK048MXkX0SOmxvA=", 505 | "owner": "numtide", 506 | "repo": "treefmt-nix", 507 | "rev": "ac599dab59a66304eb511af07b3883114f061b9d", 508 | "type": "github" 509 | }, 510 | "original": { 511 | "owner": "numtide", 512 | "repo": "treefmt-nix", 513 | "type": "github" 514 | } 515 | }, 516 | "unionmount": { 517 | "flake": false, 518 | "locked": { 519 | "lastModified": 1691619410, 520 | "narHash": "sha256-V9/OcGu9cy4kV9jta12A6w5BEj8awSEVYrXPpg8YckQ=", 521 | "owner": "srid", 522 | "repo": "unionmount", 523 | "rev": "ed73b627f88c8f021f41ba4b518ba41beff9df42", 524 | "type": "github" 525 | }, 526 | "original": { 527 | "owner": "srid", 528 | "repo": "unionmount", 529 | "type": "github" 530 | } 531 | } 532 | }, 533 | "root": "root", 534 | "version": 7 535 | } 536 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "Ema template app"; 3 | inputs = { 4 | nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; 5 | systems.url = "github:nix-systems/default"; 6 | flake-parts.url = "github:hercules-ci/flake-parts"; 7 | haskell-flake.url = "github:srid/haskell-flake"; 8 | 9 | process-compose-flake.url = "github:Platonic-Systems/process-compose-flake"; 10 | fourmolu-nix.url = "github:jedimahdi/fourmolu-nix"; 11 | git-hooks.url = "github:cachix/git-hooks.nix"; 12 | git-hooks.flake = false; 13 | 14 | ema.url = "github:srid/ema"; 15 | ema.inputs.nixpkgs.follows = "nixpkgs"; 16 | }; 17 | outputs = inputs: 18 | inputs.flake-parts.lib.mkFlake { inherit inputs; } { 19 | systems = import inputs.systems; 20 | imports = [ 21 | inputs.haskell-flake.flakeModule 22 | inputs.process-compose-flake.flakeModule 23 | inputs.fourmolu-nix.flakeModule 24 | (inputs.git-hooks + /flake-module.nix) 25 | ]; 26 | perSystem = { config, pkgs, lib, ... }: 27 | let 28 | tailwind = pkgs.haskellPackages.tailwind; 29 | in 30 | { 31 | # "haskellProjects" comes from https://github.com/srid/haskell-flake 32 | haskellProjects.default = { 33 | imports = [ 34 | inputs.ema.haskellFlakeProjectModules.output 35 | ]; 36 | autoWire = [ "packages" "apps" "checks" ]; 37 | }; 38 | 39 | pre-commit.settings = { 40 | hooks = { 41 | nixpkgs-fmt.enable = true; 42 | cabal-fmt.enable = true; 43 | fourmolu = { 44 | enable = true; 45 | package = config.fourmolu.wrapper; 46 | }; 47 | hlint.enable = true; 48 | }; 49 | }; 50 | 51 | fourmolu.settings = { 52 | indentation = 2; 53 | comma-style = "leading"; 54 | record-brace-space = true; 55 | indent-wheres = true; 56 | import-export-style = "diff-friendly"; 57 | respectful = true; 58 | haddock-style = "multi-line"; 59 | newlines-between-decls = 1; 60 | extensions = [ "ImportQualifiedPost" ]; 61 | }; 62 | 63 | process-compose."ema-tailwind-run" = { 64 | cli.environment.PC_DISABLE_TUI = true; 65 | settings = { 66 | processes = { 67 | haskell.command = "ghcid"; 68 | tailwind = { 69 | command = "${lib.getExe tailwind} -w -o ./static/tailwind.css './src/**/*.hs'"; 70 | is_tty = true; 71 | }; 72 | }; 73 | }; 74 | }; 75 | 76 | packages = 77 | let 78 | buildEmaSiteWithTailwind = { baseUrl }: 79 | pkgs.runCommand "site" 80 | { } 81 | '' 82 | mkdir -p $out 83 | pushd ${inputs.self} 84 | ${lib.getExe config.packages.ema-template} \ 85 | --base-url=${baseUrl} gen $out 86 | ${lib.getExe tailwind} \ 87 | -o $out/tailwind.css 'src/**/*.hs' 88 | ''; 89 | in 90 | { 91 | default = config.packages.ema-template; 92 | site = buildEmaSiteWithTailwind { baseUrl = "/"; }; 93 | site-github = buildEmaSiteWithTailwind { baseUrl = "/ema-template/"; }; 94 | }; 95 | 96 | devShells.default = pkgs.mkShell { 97 | name = "ema-template"; 98 | meta.description = "ema-template development environment"; 99 | packages = [ 100 | tailwind 101 | pkgs.just 102 | pkgs.nixd 103 | ]; 104 | inputsFrom = [ 105 | config.haskellProjects.default.outputs.devShell 106 | config.pre-commit.devShell 107 | ]; 108 | }; 109 | }; 110 | }; 111 | } 112 | -------------------------------------------------------------------------------- /justfile: -------------------------------------------------------------------------------- 1 | default: 2 | @just --list 3 | 4 | # Run hoogle 5 | docs: 6 | echo http://127.0.0.1:8888 7 | hoogle serve -p 8888 --local 8 | 9 | # Run cabal repl 10 | repl *ARGS: 11 | cabal repl {{ARGS}} 12 | 13 | # Run the dev server (ghcid + tailwind) 14 | run: 15 | nix run .#ema-tailwind-run 16 | -------------------------------------------------------------------------------- /src/Main.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskell #-} 2 | {-# LANGUAGE UndecidableInstances #-} 3 | 4 | module Main where 5 | 6 | import Data.Default (def) 7 | import Data.Generics.Sum.Any (AsAny (_As)) 8 | import Ema 9 | import Ema.CLI qualified 10 | import Ema.Route.Generic.TH 11 | import Ema.Route.Lib.Extra.StaticRoute qualified as SR 12 | import Lucid 13 | import Optics.Core (Prism', (%)) 14 | import Options.Applicative 15 | 16 | data Model = Model 17 | { modelBaseUrl :: Text 18 | , modelStatic :: SR.Model 19 | } 20 | deriving stock (Eq, Show, Generic) 21 | 22 | data HtmlRoute 23 | = HtmlRoute_Index 24 | | HtmlRoute_About 25 | deriving stock (Show, Eq, Ord, Generic, Enum, Bounded) 26 | 27 | deriveGeneric ''HtmlRoute 28 | deriveIsRoute ''HtmlRoute [t|'[]|] 29 | 30 | type StaticRoute = SR.StaticRoute "static" 31 | 32 | data Route 33 | = Route_Html HtmlRoute 34 | | Route_Static StaticRoute 35 | deriving stock (Eq, Show, Ord, Generic) 36 | 37 | deriveGeneric ''Route 38 | deriveIsRoute 39 | ''Route 40 | [t| 41 | [ -- To render a `Route` we need `Model` 42 | WithModel Model 43 | , -- Override default sub-route encoding (to avoid the folder prefix in encoded URLs) 44 | WithSubRoutes [HtmlRoute, StaticRoute] 45 | ] 46 | |] 47 | 48 | instance EmaSite Route where 49 | type SiteArg Route = CliArgs 50 | siteInput cliAct args = do 51 | staticRouteDyn <- siteInput @StaticRoute cliAct () 52 | pure $ Model (cliArgsBaseUrl args) <$> staticRouteDyn 53 | siteOutput rp m = \case 54 | Route_Html r -> 55 | pure $ Ema.AssetGenerated Ema.Html $ renderHtmlRoute rp m r 56 | Route_Static r -> 57 | siteOutput (rp % (_As @"Route_Static")) (modelStatic m) r 58 | 59 | renderHtmlRoute :: Prism' FilePath Route -> Model -> HtmlRoute -> LByteString 60 | renderHtmlRoute rp m r = do 61 | renderBS $ doctypehtml_ $ do 62 | head_ $ renderHead rp m r 63 | body_ [class_ "bg-gray-50"] $ renderBody rp m r 64 | 65 | renderHead :: Prism' FilePath Route -> Model -> HtmlRoute -> Html () 66 | renderHead rp model r = do 67 | meta_ [charset_ "UTF-8"] 68 | meta_ [name_ "viewport", content_ "width=device-width, initial-scale=1"] 69 | title_ $ toHtml $ routeTitle r <> " - Ema Template" 70 | base_ [href_ $ modelBaseUrl model] 71 | link_ [rel_ "stylesheet", href_ $ staticRouteUrl rp model "tailwind.css"] 72 | 73 | renderBody :: Prism' FilePath Route -> Model -> HtmlRoute -> Html () 74 | renderBody rp model r = do 75 | div_ [class_ "container mx-auto mt-8 p-4 max-w-prose border-2 bg-white rounded-lg shadow"] $ do 76 | renderNavbar rp r 77 | h1_ [class_ "text-3xl font-bold"] $ toHtml $ routeTitle r 78 | case r of 79 | HtmlRoute_Index -> do 80 | "You are on the index page. Want to see " 81 | routeLink rp HtmlRoute_About "About" 82 | "?" 83 | HtmlRoute_About -> do 84 | "You are on the about page." 85 | a_ [href_ $ staticRouteUrl rp model "logo.svg", target_ "_blank"] $ do 86 | img_ [src_ $ staticRouteUrl rp model "logo.svg", class_ "py-4 w-32", alt_ "Ema Logo"] 87 | 88 | renderNavbar :: Prism' FilePath Route -> HtmlRoute -> Html () 89 | renderNavbar rp currentRoute = 90 | nav_ [class_ "w-full text-xl font-bold flex space-x-4 mb-4"] $ do 91 | forM_ (universe @HtmlRoute) $ \r -> 92 | let extraClass = if r == currentRoute then "bg-rose-400 text-white" else "text-gray-700" 93 | in a_ 94 | [ href_ $ routeUrl rp $ Route_Html r 95 | , class_ $ "rounded p-2 " <> extraClass 96 | ] 97 | $ toHtml 98 | $ routeTitle r 99 | 100 | routeTitle :: HtmlRoute -> Text 101 | routeTitle r = case r of 102 | HtmlRoute_Index -> "Home" 103 | HtmlRoute_About -> "About" 104 | 105 | routeLink :: Prism' FilePath Route -> HtmlRoute -> Html () -> Html () 106 | routeLink rp r = 107 | a_ 108 | [ href_ $ routeUrl rp $ Route_Html r 109 | , class_ "text-rose-400" 110 | ] 111 | 112 | -- | Link to a file under ./static 113 | staticRouteUrl :: (IsString r) => Prism' FilePath Route -> Model -> FilePath -> r 114 | staticRouteUrl rp m = 115 | SR.staticRouteUrl (rp % (_As @"Route_Static")) (modelStatic m) 116 | 117 | -- CLI argument handling 118 | -- --------------------- 119 | 120 | data CliArgs = CliArgs 121 | { cliArgsBaseUrl :: Text 122 | , cliArgsEmaCli :: Ema.CLI.Cli 123 | } 124 | deriving stock (Eq, Show) 125 | 126 | parseCliArgs :: IO CliArgs 127 | parseCliArgs = 128 | execParser $ parserInfo cliParser 129 | where 130 | cliParser :: Parser CliArgs 131 | cliParser = 132 | CliArgs 133 | <$> option str (long "base-url" <> metavar "BASE_URL" <> help "Base URL to use in " <> value "/") 134 | <*> Ema.CLI.cliParser 135 | parserInfo :: Parser a -> ParserInfo a 136 | parserInfo p = 137 | info 138 | (versionOption <*> p <**> helper) 139 | ( fullDesc 140 | <> progDesc "ema-template: TODO" 141 | <> header "ema-template" 142 | ) 143 | where 144 | versionOption = infoOption "0.1" (long "version" <> help "Show version") 145 | 146 | -- Main entrypoint 147 | -- --------------- 148 | 149 | main :: IO () 150 | main = do 151 | cliArgs <- parseCliArgs 152 | let cfg = SiteConfig (cliArgsEmaCli cliArgs) def 153 | void $ Ema.runSiteWith @Route cfg cliArgs 154 | -------------------------------------------------------------------------------- /static/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 17 | 20 | 21 | 23 | 24 | 25 | 27 | 28 | 29 | 32 | 33 | 34 | 36 | 37 | 38 | 40 | 41 | 42 | 45 | 46 | 50 | 51 | 53 | 54 | 55 | 57 | 58 | 59 | 60 | 63 | 64 | 65 | 68 | 69 | 73 | 74 | 75 | 76 | 77 | 79 | 80 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /static/tailwind.css: -------------------------------------------------------------------------------- 1 | *, ::before, ::after { 2 | --tw-border-spacing-x: 0; 3 | --tw-border-spacing-y: 0; 4 | --tw-translate-x: 0; 5 | --tw-translate-y: 0; 6 | --tw-rotate: 0; 7 | --tw-skew-x: 0; 8 | --tw-skew-y: 0; 9 | --tw-scale-x: 1; 10 | --tw-scale-y: 1; 11 | --tw-pan-x: ; 12 | --tw-pan-y: ; 13 | --tw-pinch-zoom: ; 14 | --tw-scroll-snap-strictness: proximity; 15 | --tw-gradient-from-position: ; 16 | --tw-gradient-via-position: ; 17 | --tw-gradient-to-position: ; 18 | --tw-ordinal: ; 19 | --tw-slashed-zero: ; 20 | --tw-numeric-figure: ; 21 | --tw-numeric-spacing: ; 22 | --tw-numeric-fraction: ; 23 | --tw-ring-inset: ; 24 | --tw-ring-offset-width: 0px; 25 | --tw-ring-offset-color: #fff; 26 | --tw-ring-color: rgb(59 130 246 / 0.5); 27 | --tw-ring-offset-shadow: 0 0 #0000; 28 | --tw-ring-shadow: 0 0 #0000; 29 | --tw-shadow: 0 0 #0000; 30 | --tw-shadow-colored: 0 0 #0000; 31 | --tw-blur: ; 32 | --tw-brightness: ; 33 | --tw-contrast: ; 34 | --tw-grayscale: ; 35 | --tw-hue-rotate: ; 36 | --tw-invert: ; 37 | --tw-saturate: ; 38 | --tw-sepia: ; 39 | --tw-drop-shadow: ; 40 | --tw-backdrop-blur: ; 41 | --tw-backdrop-brightness: ; 42 | --tw-backdrop-contrast: ; 43 | --tw-backdrop-grayscale: ; 44 | --tw-backdrop-hue-rotate: ; 45 | --tw-backdrop-invert: ; 46 | --tw-backdrop-opacity: ; 47 | --tw-backdrop-saturate: ; 48 | --tw-backdrop-sepia: ; 49 | --tw-contain-size: ; 50 | --tw-contain-layout: ; 51 | --tw-contain-paint: ; 52 | --tw-contain-style: ; 53 | } 54 | 55 | ::backdrop { 56 | --tw-border-spacing-x: 0; 57 | --tw-border-spacing-y: 0; 58 | --tw-translate-x: 0; 59 | --tw-translate-y: 0; 60 | --tw-rotate: 0; 61 | --tw-skew-x: 0; 62 | --tw-skew-y: 0; 63 | --tw-scale-x: 1; 64 | --tw-scale-y: 1; 65 | --tw-pan-x: ; 66 | --tw-pan-y: ; 67 | --tw-pinch-zoom: ; 68 | --tw-scroll-snap-strictness: proximity; 69 | --tw-gradient-from-position: ; 70 | --tw-gradient-via-position: ; 71 | --tw-gradient-to-position: ; 72 | --tw-ordinal: ; 73 | --tw-slashed-zero: ; 74 | --tw-numeric-figure: ; 75 | --tw-numeric-spacing: ; 76 | --tw-numeric-fraction: ; 77 | --tw-ring-inset: ; 78 | --tw-ring-offset-width: 0px; 79 | --tw-ring-offset-color: #fff; 80 | --tw-ring-color: rgb(59 130 246 / 0.5); 81 | --tw-ring-offset-shadow: 0 0 #0000; 82 | --tw-ring-shadow: 0 0 #0000; 83 | --tw-shadow: 0 0 #0000; 84 | --tw-shadow-colored: 0 0 #0000; 85 | --tw-blur: ; 86 | --tw-brightness: ; 87 | --tw-contrast: ; 88 | --tw-grayscale: ; 89 | --tw-hue-rotate: ; 90 | --tw-invert: ; 91 | --tw-saturate: ; 92 | --tw-sepia: ; 93 | --tw-drop-shadow: ; 94 | --tw-backdrop-blur: ; 95 | --tw-backdrop-brightness: ; 96 | --tw-backdrop-contrast: ; 97 | --tw-backdrop-grayscale: ; 98 | --tw-backdrop-hue-rotate: ; 99 | --tw-backdrop-invert: ; 100 | --tw-backdrop-opacity: ; 101 | --tw-backdrop-saturate: ; 102 | --tw-backdrop-sepia: ; 103 | --tw-contain-size: ; 104 | --tw-contain-layout: ; 105 | --tw-contain-paint: ; 106 | --tw-contain-style: ; 107 | } 108 | 109 | /* 110 | ! tailwindcss v3.4.12 | MIT License | https://tailwindcss.com 111 | */ 112 | 113 | /* 114 | 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) 115 | 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) 116 | */ 117 | 118 | *, 119 | ::before, 120 | ::after { 121 | box-sizing: border-box; 122 | /* 1 */ 123 | border-width: 0; 124 | /* 2 */ 125 | border-style: solid; 126 | /* 2 */ 127 | border-color: #e5e7eb; 128 | /* 2 */ 129 | } 130 | 131 | ::before, 132 | ::after { 133 | --tw-content: ''; 134 | } 135 | 136 | /* 137 | 1. Use a consistent sensible line-height in all browsers. 138 | 2. Prevent adjustments of font size after orientation changes in iOS. 139 | 3. Use a more readable tab size. 140 | 4. Use the user's configured `sans` font-family by default. 141 | 5. Use the user's configured `sans` font-feature-settings by default. 142 | 6. Use the user's configured `sans` font-variation-settings by default. 143 | 7. Disable tap highlights on iOS 144 | */ 145 | 146 | html, 147 | :host { 148 | line-height: 1.5; 149 | /* 1 */ 150 | -webkit-text-size-adjust: 100%; 151 | /* 2 */ 152 | -moz-tab-size: 4; 153 | /* 3 */ 154 | -o-tab-size: 4; 155 | tab-size: 4; 156 | /* 3 */ 157 | font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; 158 | /* 4 */ 159 | font-feature-settings: normal; 160 | /* 5 */ 161 | font-variation-settings: normal; 162 | /* 6 */ 163 | -webkit-tap-highlight-color: transparent; 164 | /* 7 */ 165 | } 166 | 167 | /* 168 | 1. Remove the margin in all browsers. 169 | 2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. 170 | */ 171 | 172 | body { 173 | margin: 0; 174 | /* 1 */ 175 | line-height: inherit; 176 | /* 2 */ 177 | } 178 | 179 | /* 180 | 1. Add the correct height in Firefox. 181 | 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) 182 | 3. Ensure horizontal rules are visible by default. 183 | */ 184 | 185 | hr { 186 | height: 0; 187 | /* 1 */ 188 | color: inherit; 189 | /* 2 */ 190 | border-top-width: 1px; 191 | /* 3 */ 192 | } 193 | 194 | /* 195 | Add the correct text decoration in Chrome, Edge, and Safari. 196 | */ 197 | 198 | abbr:where([title]) { 199 | -webkit-text-decoration: underline dotted; 200 | text-decoration: underline dotted; 201 | } 202 | 203 | /* 204 | Remove the default font size and weight for headings. 205 | */ 206 | 207 | h1, 208 | h2, 209 | h3, 210 | h4, 211 | h5, 212 | h6 { 213 | font-size: inherit; 214 | font-weight: inherit; 215 | } 216 | 217 | /* 218 | Reset links to optimize for opt-in styling instead of opt-out. 219 | */ 220 | 221 | a { 222 | color: inherit; 223 | text-decoration: inherit; 224 | } 225 | 226 | /* 227 | Add the correct font weight in Edge and Safari. 228 | */ 229 | 230 | b, 231 | strong { 232 | font-weight: bolder; 233 | } 234 | 235 | /* 236 | 1. Use the user's configured `mono` font-family by default. 237 | 2. Use the user's configured `mono` font-feature-settings by default. 238 | 3. Use the user's configured `mono` font-variation-settings by default. 239 | 4. Correct the odd `em` font sizing in all browsers. 240 | */ 241 | 242 | code, 243 | kbd, 244 | samp, 245 | pre { 246 | font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; 247 | /* 1 */ 248 | font-feature-settings: normal; 249 | /* 2 */ 250 | font-variation-settings: normal; 251 | /* 3 */ 252 | font-size: 1em; 253 | /* 4 */ 254 | } 255 | 256 | /* 257 | Add the correct font size in all browsers. 258 | */ 259 | 260 | small { 261 | font-size: 80%; 262 | } 263 | 264 | /* 265 | Prevent `sub` and `sup` elements from affecting the line height in all browsers. 266 | */ 267 | 268 | sub, 269 | sup { 270 | font-size: 75%; 271 | line-height: 0; 272 | position: relative; 273 | vertical-align: baseline; 274 | } 275 | 276 | sub { 277 | bottom: -0.25em; 278 | } 279 | 280 | sup { 281 | top: -0.5em; 282 | } 283 | 284 | /* 285 | 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) 286 | 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) 287 | 3. Remove gaps between table borders by default. 288 | */ 289 | 290 | table { 291 | text-indent: 0; 292 | /* 1 */ 293 | border-color: inherit; 294 | /* 2 */ 295 | border-collapse: collapse; 296 | /* 3 */ 297 | } 298 | 299 | /* 300 | 1. Change the font styles in all browsers. 301 | 2. Remove the margin in Firefox and Safari. 302 | 3. Remove default padding in all browsers. 303 | */ 304 | 305 | button, 306 | input, 307 | optgroup, 308 | select, 309 | textarea { 310 | font-family: inherit; 311 | /* 1 */ 312 | font-feature-settings: inherit; 313 | /* 1 */ 314 | font-variation-settings: inherit; 315 | /* 1 */ 316 | font-size: 100%; 317 | /* 1 */ 318 | font-weight: inherit; 319 | /* 1 */ 320 | line-height: inherit; 321 | /* 1 */ 322 | letter-spacing: inherit; 323 | /* 1 */ 324 | color: inherit; 325 | /* 1 */ 326 | margin: 0; 327 | /* 2 */ 328 | padding: 0; 329 | /* 3 */ 330 | } 331 | 332 | /* 333 | Remove the inheritance of text transform in Edge and Firefox. 334 | */ 335 | 336 | button, 337 | select { 338 | text-transform: none; 339 | } 340 | 341 | /* 342 | 1. Correct the inability to style clickable types in iOS and Safari. 343 | 2. Remove default button styles. 344 | */ 345 | 346 | button, 347 | input:where([type='button']), 348 | input:where([type='reset']), 349 | input:where([type='submit']) { 350 | -webkit-appearance: button; 351 | /* 1 */ 352 | background-color: transparent; 353 | /* 2 */ 354 | background-image: none; 355 | /* 2 */ 356 | } 357 | 358 | /* 359 | Use the modern Firefox focus style for all focusable elements. 360 | */ 361 | 362 | :-moz-focusring { 363 | outline: auto; 364 | } 365 | 366 | /* 367 | Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) 368 | */ 369 | 370 | :-moz-ui-invalid { 371 | box-shadow: none; 372 | } 373 | 374 | /* 375 | Add the correct vertical alignment in Chrome and Firefox. 376 | */ 377 | 378 | progress { 379 | vertical-align: baseline; 380 | } 381 | 382 | /* 383 | Correct the cursor style of increment and decrement buttons in Safari. 384 | */ 385 | 386 | ::-webkit-inner-spin-button, 387 | ::-webkit-outer-spin-button { 388 | height: auto; 389 | } 390 | 391 | /* 392 | 1. Correct the odd appearance in Chrome and Safari. 393 | 2. Correct the outline style in Safari. 394 | */ 395 | 396 | [type='search'] { 397 | -webkit-appearance: textfield; 398 | /* 1 */ 399 | outline-offset: -2px; 400 | /* 2 */ 401 | } 402 | 403 | /* 404 | Remove the inner padding in Chrome and Safari on macOS. 405 | */ 406 | 407 | ::-webkit-search-decoration { 408 | -webkit-appearance: none; 409 | } 410 | 411 | /* 412 | 1. Correct the inability to style clickable types in iOS and Safari. 413 | 2. Change font properties to `inherit` in Safari. 414 | */ 415 | 416 | ::-webkit-file-upload-button { 417 | -webkit-appearance: button; 418 | /* 1 */ 419 | font: inherit; 420 | /* 2 */ 421 | } 422 | 423 | /* 424 | Add the correct display in Chrome and Safari. 425 | */ 426 | 427 | summary { 428 | display: list-item; 429 | } 430 | 431 | /* 432 | Removes the default spacing and border for appropriate elements. 433 | */ 434 | 435 | blockquote, 436 | dl, 437 | dd, 438 | h1, 439 | h2, 440 | h3, 441 | h4, 442 | h5, 443 | h6, 444 | hr, 445 | figure, 446 | p, 447 | pre { 448 | margin: 0; 449 | } 450 | 451 | fieldset { 452 | margin: 0; 453 | padding: 0; 454 | } 455 | 456 | legend { 457 | padding: 0; 458 | } 459 | 460 | ol, 461 | ul, 462 | menu { 463 | list-style: none; 464 | margin: 0; 465 | padding: 0; 466 | } 467 | 468 | /* 469 | Reset default styling for dialogs. 470 | */ 471 | 472 | dialog { 473 | padding: 0; 474 | } 475 | 476 | /* 477 | Prevent resizing textareas horizontally by default. 478 | */ 479 | 480 | textarea { 481 | resize: vertical; 482 | } 483 | 484 | /* 485 | 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) 486 | 2. Set the default placeholder color to the user's configured gray 400 color. 487 | */ 488 | 489 | input::-moz-placeholder, textarea::-moz-placeholder { 490 | opacity: 1; 491 | /* 1 */ 492 | color: #9ca3af; 493 | /* 2 */ 494 | } 495 | 496 | input::placeholder, 497 | textarea::placeholder { 498 | opacity: 1; 499 | /* 1 */ 500 | color: #9ca3af; 501 | /* 2 */ 502 | } 503 | 504 | /* 505 | Set the default cursor for buttons. 506 | */ 507 | 508 | button, 509 | [role="button"] { 510 | cursor: pointer; 511 | } 512 | 513 | /* 514 | Make sure disabled buttons don't get the pointer cursor. 515 | */ 516 | 517 | :disabled { 518 | cursor: default; 519 | } 520 | 521 | /* 522 | 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) 523 | 2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) 524 | This can trigger a poorly considered lint error in some tools but is included by design. 525 | */ 526 | 527 | img, 528 | svg, 529 | video, 530 | canvas, 531 | audio, 532 | iframe, 533 | embed, 534 | object { 535 | display: block; 536 | /* 1 */ 537 | vertical-align: middle; 538 | /* 2 */ 539 | } 540 | 541 | /* 542 | Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) 543 | */ 544 | 545 | img, 546 | video { 547 | max-width: 100%; 548 | height: auto; 549 | } 550 | 551 | /* Make elements with the HTML hidden attribute stay hidden by default */ 552 | 553 | [hidden] { 554 | display: none; 555 | } 556 | 557 | [type='text'],input:where(:not([type])),[type='email'],[type='url'],[type='password'],[type='number'],[type='date'],[type='datetime-local'],[type='month'],[type='search'],[type='tel'],[type='time'],[type='week'],[multiple],textarea,select { 558 | -webkit-appearance: none; 559 | -moz-appearance: none; 560 | appearance: none; 561 | background-color: #fff; 562 | border-color: #6b7280; 563 | border-width: 1px; 564 | border-radius: 0px; 565 | padding-top: 0.5rem; 566 | padding-right: 0.75rem; 567 | padding-bottom: 0.5rem; 568 | padding-left: 0.75rem; 569 | font-size: 1rem; 570 | line-height: 1.5rem; 571 | --tw-shadow: 0 0 #0000; 572 | } 573 | 574 | [type='text']:focus, input:where(:not([type])):focus, [type='email']:focus, [type='url']:focus, [type='password']:focus, [type='number']:focus, [type='date']:focus, [type='datetime-local']:focus, [type='month']:focus, [type='search']:focus, [type='tel']:focus, [type='time']:focus, [type='week']:focus, [multiple]:focus, textarea:focus, select:focus { 575 | outline: 2px solid transparent; 576 | outline-offset: 2px; 577 | --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); 578 | --tw-ring-offset-width: 0px; 579 | --tw-ring-offset-color: #fff; 580 | --tw-ring-color: #2563eb; 581 | --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); 582 | --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); 583 | box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); 584 | border-color: #2563eb; 585 | } 586 | 587 | input::-moz-placeholder, textarea::-moz-placeholder { 588 | color: #6b7280; 589 | opacity: 1; 590 | } 591 | 592 | input::placeholder,textarea::placeholder { 593 | color: #6b7280; 594 | opacity: 1; 595 | } 596 | 597 | ::-webkit-datetime-edit-fields-wrapper { 598 | padding: 0; 599 | } 600 | 601 | ::-webkit-date-and-time-value { 602 | min-height: 1.5em; 603 | text-align: inherit; 604 | } 605 | 606 | ::-webkit-datetime-edit { 607 | display: inline-flex; 608 | } 609 | 610 | ::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field { 611 | padding-top: 0; 612 | padding-bottom: 0; 613 | } 614 | 615 | select { 616 | background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e"); 617 | background-position: right 0.5rem center; 618 | background-repeat: no-repeat; 619 | background-size: 1.5em 1.5em; 620 | padding-right: 2.5rem; 621 | -webkit-print-color-adjust: exact; 622 | print-color-adjust: exact; 623 | } 624 | 625 | [multiple],[size]:where(select:not([size="1"])) { 626 | background-image: initial; 627 | background-position: initial; 628 | background-repeat: unset; 629 | background-size: initial; 630 | padding-right: 0.75rem; 631 | -webkit-print-color-adjust: unset; 632 | print-color-adjust: unset; 633 | } 634 | 635 | [type='checkbox'],[type='radio'] { 636 | -webkit-appearance: none; 637 | -moz-appearance: none; 638 | appearance: none; 639 | padding: 0; 640 | -webkit-print-color-adjust: exact; 641 | print-color-adjust: exact; 642 | display: inline-block; 643 | vertical-align: middle; 644 | background-origin: border-box; 645 | -webkit-user-select: none; 646 | -moz-user-select: none; 647 | user-select: none; 648 | flex-shrink: 0; 649 | height: 1rem; 650 | width: 1rem; 651 | color: #2563eb; 652 | background-color: #fff; 653 | border-color: #6b7280; 654 | border-width: 1px; 655 | --tw-shadow: 0 0 #0000; 656 | } 657 | 658 | [type='checkbox'] { 659 | border-radius: 0px; 660 | } 661 | 662 | [type='radio'] { 663 | border-radius: 100%; 664 | } 665 | 666 | [type='checkbox']:focus,[type='radio']:focus { 667 | outline: 2px solid transparent; 668 | outline-offset: 2px; 669 | --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); 670 | --tw-ring-offset-width: 2px; 671 | --tw-ring-offset-color: #fff; 672 | --tw-ring-color: #2563eb; 673 | --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); 674 | --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); 675 | box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); 676 | } 677 | 678 | [type='checkbox']:checked,[type='radio']:checked { 679 | border-color: transparent; 680 | background-color: currentColor; 681 | background-size: 100% 100%; 682 | background-position: center; 683 | background-repeat: no-repeat; 684 | } 685 | 686 | [type='checkbox']:checked { 687 | background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e"); 688 | } 689 | 690 | @media (forced-colors: active) { 691 | [type='checkbox']:checked { 692 | -webkit-appearance: auto; 693 | -moz-appearance: auto; 694 | appearance: auto; 695 | } 696 | } 697 | 698 | [type='radio']:checked { 699 | background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e"); 700 | } 701 | 702 | @media (forced-colors: active) { 703 | [type='radio']:checked { 704 | -webkit-appearance: auto; 705 | -moz-appearance: auto; 706 | appearance: auto; 707 | } 708 | } 709 | 710 | [type='checkbox']:checked:hover,[type='checkbox']:checked:focus,[type='radio']:checked:hover,[type='radio']:checked:focus { 711 | border-color: transparent; 712 | background-color: currentColor; 713 | } 714 | 715 | [type='checkbox']:indeterminate { 716 | background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e"); 717 | border-color: transparent; 718 | background-color: currentColor; 719 | background-size: 100% 100%; 720 | background-position: center; 721 | background-repeat: no-repeat; 722 | } 723 | 724 | @media (forced-colors: active) { 725 | [type='checkbox']:indeterminate { 726 | -webkit-appearance: auto; 727 | -moz-appearance: auto; 728 | appearance: auto; 729 | } 730 | } 731 | 732 | [type='checkbox']:indeterminate:hover,[type='checkbox']:indeterminate:focus { 733 | border-color: transparent; 734 | background-color: currentColor; 735 | } 736 | 737 | [type='file'] { 738 | background: unset; 739 | border-color: inherit; 740 | border-width: 0; 741 | border-radius: 0; 742 | padding: 0; 743 | font-size: unset; 744 | line-height: inherit; 745 | } 746 | 747 | [type='file']:focus { 748 | outline: 1px solid ButtonText; 749 | outline: 1px auto -webkit-focus-ring-color; 750 | } 751 | 752 | .container { 753 | width: 100%; 754 | } 755 | 756 | @media (min-width: 640px) { 757 | .container { 758 | max-width: 640px; 759 | } 760 | } 761 | 762 | @media (min-width: 768px) { 763 | .container { 764 | max-width: 768px; 765 | } 766 | } 767 | 768 | @media (min-width: 1024px) { 769 | .container { 770 | max-width: 1024px; 771 | } 772 | } 773 | 774 | @media (min-width: 1280px) { 775 | .container { 776 | max-width: 1280px; 777 | } 778 | } 779 | 780 | @media (min-width: 1536px) { 781 | .container { 782 | max-width: 1536px; 783 | } 784 | } 785 | 786 | .static { 787 | position: static; 788 | } 789 | 790 | .mx-auto { 791 | margin-left: auto; 792 | margin-right: auto; 793 | } 794 | 795 | .mb-4 { 796 | margin-bottom: 1rem; 797 | } 798 | 799 | .mt-8 { 800 | margin-top: 2rem; 801 | } 802 | 803 | .flex { 804 | display: flex; 805 | } 806 | 807 | .w-32 { 808 | width: 8rem; 809 | } 810 | 811 | .w-full { 812 | width: 100%; 813 | } 814 | 815 | .max-w-prose { 816 | max-width: 65ch; 817 | } 818 | 819 | .space-x-4 > :not([hidden]) ~ :not([hidden]) { 820 | --tw-space-x-reverse: 0; 821 | margin-right: calc(1rem * var(--tw-space-x-reverse)); 822 | margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse))); 823 | } 824 | 825 | .rounded { 826 | border-radius: 0.25rem; 827 | } 828 | 829 | .rounded-lg { 830 | border-radius: 0.5rem; 831 | } 832 | 833 | .border-2 { 834 | border-width: 2px; 835 | } 836 | 837 | .bg-gray-50 { 838 | --tw-bg-opacity: 1; 839 | background-color: rgb(249 250 251 / var(--tw-bg-opacity)); 840 | } 841 | 842 | .bg-rose-400 { 843 | --tw-bg-opacity: 1; 844 | background-color: rgb(251 113 133 / var(--tw-bg-opacity)); 845 | } 846 | 847 | .bg-white { 848 | --tw-bg-opacity: 1; 849 | background-color: rgb(255 255 255 / var(--tw-bg-opacity)); 850 | } 851 | 852 | .p-2 { 853 | padding: 0.5rem; 854 | } 855 | 856 | .p-4 { 857 | padding: 1rem; 858 | } 859 | 860 | .py-4 { 861 | padding-top: 1rem; 862 | padding-bottom: 1rem; 863 | } 864 | 865 | .text-3xl { 866 | font-size: 1.875rem; 867 | line-height: 2.25rem; 868 | } 869 | 870 | .text-xl { 871 | font-size: 1.25rem; 872 | line-height: 1.75rem; 873 | } 874 | 875 | .font-bold { 876 | font-weight: 700; 877 | } 878 | 879 | .text-gray-700 { 880 | --tw-text-opacity: 1; 881 | color: rgb(55 65 81 / var(--tw-text-opacity)); 882 | } 883 | 884 | .text-rose-400 { 885 | --tw-text-opacity: 1; 886 | color: rgb(251 113 133 / var(--tw-text-opacity)); 887 | } 888 | 889 | .text-white { 890 | --tw-text-opacity: 1; 891 | color: rgb(255 255 255 / var(--tw-text-opacity)); 892 | } 893 | 894 | .shadow { 895 | --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); 896 | --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); 897 | box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); 898 | } --------------------------------------------------------------------------------