Protolude
A sensible starting Prelude for building custom Preludes.
Design points:
- Banishes String.
- Banishes partial functions.
- Compiler warning on bottoms.
- Polymorphic string IO functions.
- Polymorphic show.
- Automatic string conversions.
- Types for common data structures in scope.
- Types for all common string types (Text/ByteString) in scope.
- Banishes impure exception throwing outside of IO.
- StateT/ReaderT/ExceptT transformers in scope by default.
- Foldable / Traversable functions in scope by default.
- Unsafe functions are prefixed with “unsafe” in separate module.
- Compiler agnostic, GHC internal modules are abstracted out into Base.
sum
and product
are strict by default.
- Compatibility with GHC 8.0.
- Includes Semiring for GHC >= 7.6.
- Includes Bifunctor for GHC >= 7.6.
- Includes Semigroup for GHC >= 7.6.
Supports:
- GHC 7.6.1
- GHC 7.6.2
- GHC 7.6.3
- GHC 7.8.1
- GHC 7.8.2
- GHC 7.8.3
- GHC 7.8.4
- GHC 7.10.1
- GHC 7.10.2
- GHC 7.10.3
- GHC 8.0.1
- GHC 8.0.2
- GHC 8.2.1
- GHC 8.4.1
- GHC 8.6.1
Usage
To try out standalone prelude at the interactive shell, from the Protolude
project directory run.
$ stack exec ghci
> import Protolude
Swapping out the old Prelude
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
Exported Functions
The list of exports is given in the Symbols.md file. Haddock
unfortunately breaks in the presence of module reexports and is unable to render
documentation.
Dependencies
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.13 |
bytestring |
0.10 |
0.11 |
containers |
0.5 |
0.7 |
deepseq |
1.3 |
1.5 |
ghc-prim |
0.3 |
0.6 |
hashable |
1.2 |
1.3 |
mtl |
2.1 |
2.3 |
stm |
2.4 |
2.6 |
text |
1.2 |
1.3 |
transformers |
0.4 |
0.6 |
|
|
|
Structure
Protolude’s main modules are the following:
FAQs
- My
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 ()
- How do I write manual Show instances if
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.
- Partial functions like
undefined
and error
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.
It has been renamed to identity
to reserve the id
identifier for the
more common use case of business logic.
License
Released under the MIT License.
Copyright (c) 2016-2018, Stephen Diehl