A sensible starting Prelude template.
A sensible starting Prelude for building custom Preludes.
Design points:
sum
and product
are strict by default.Supports:
Stack LTS:
To try out standalone prelude at the interactive shell, from the Protolude project directory run.
$ stack repl
> import Protolude
Disable the built-in prelude at the top of your file:
{-# LANGUAGE NoImplicitPrelude #-}
Or directly in your project cabal file:
default-extensions: NoImplicitPrelude
Then in your modules:
import Protolude
Protolude tries to be light on dependencies and only pulls in essential libraries that are universally common across most real-world projects. Lower and upper bounds are fully specified and compatible with both vanilla Cabal and tracks Stack LTS resolver.
Dependencies | Lower (>=) | Upper (<) |
---|---|---|
array | 0.4 | 0.6 |
async | 2.0 | 2.3 |
base | 4.6 | 4.16 |
bytestring | 0.10 | 0.11 |
containers | 0.5 | 0.7 |
deepseq | 1.3 | 1.5 |
ghc-prim | 0.3 | 0.7 |
hashable | 1.2 | 1.4 |
mtl | 2.1 | 2.3 |
stm | 2.4 | 2.6 |
text | 1.2 | 1.3 |
transformers | 0.4 | 0.6 |
fail | 4.9 | 4.10 |
Protolude's main modules are the following:
putStrLn
and putStr
instances are no longer inferred in the presense
of the -XOverloadedStrings
extension?
Because the print functions are polymorphic the type of the print functions may require annotations if the type is not fully specified by inference. To force a specific type at the call site use either
putText :: MonadIO m => T.Text -> m ()
putLText :: MonadIO m => TL.Text -> m ()
show
isn't provided?
Generally speaking writing manual instances of Show is a Haskell antipattern because it produces law-violating instances of Show. You probably want to use a pretty printer library for custom printing.
If backwards compatibility is needed then the base library can be imported manually.
import GHC.Show (Show(..))
Automatic deriving of Show
for your types is still supported since the class
is in scope by default.
undefined
raise compiler warnings on
usage.
This is by design. For fatal uncatchable errors use the provided panic
function if you intend the program to immediately abort.
panic "Thus I die. Thus, thus, thus. Now I am dead"
If inside of IO simply use throwIO
for exception handling, or if in pure
business logic use well-typed checked exceptions of the ExceptT
variety.
id
not in scope?
It has been renamed to identity
to reserve the id
identifier for the
more common use case of business logic.
You if you need partial functions for backwards compatibility you can use the
Protolude.Partial
module and mask the safe definitions as needed.
import Protolude hiding (head)
import Protolude.Partial (head)
GHC Magic
To build the exports
management tool use:
$ cabal new-build exports --flag dev
$ cabal run exports
This tool uses GHC's internal compile symbol table to generate a list of exports and keep the export list of protolude stable across different versions of GHC and base.
Continious Integration
There is a massive test suite that tests all versions of GHC 7.6 - GHC HEAD alongside all Stack resolvers to ensure no regressions. Any pull requests or patch has to pass the 47 integrity checks before being considered. Any pull request must keep the export list consistent across GHC and Base version and not have any accidental symbol dropping or drift without updating the export golden tests.
Released under the MIT License. Copyright (c) 2016-2022, Stephen Diehl