- Haskell 100%
Antelude #
Yet another alternative Prelude for Haskell.
https://english.stackexchange.com/questions/554704/difference-between-the-prefixes-pre-and-ante :
- ante (w/acc) > location and direction (ante + chamber = before the room, --> towards it) whereas > (ante + mortem = before death <-- prior to it)
- prae (w/abl) > place where = position (pre + fer = put before --above all)
Motivation #
I came into Haskell from learning Elm, enjoying Elm, and wanting a familiar way of programming for backend-type code. While Haskell is one of the closest relatives (syntax/style-wise, obviously not in purpose), there are parts that are very different and were at-first confusing. NRI made a prelude that mimics closely things Elm developers may be familiar with, to ease them into it, and fix up some of the standard Prelude where applicable: NRI Prelude
On the other hand, I had also come across Relude. Compared to the NRI-Prelude, Relude tries to keep things familiar for the existing Haskell developers, while also doing its own opinionated fixing of some of the flaws of the standard Prelude.
While these are both great options (and there are also others out there!), I began to have ideas on how I wanted to work with Haskell. And a large portion of the time, the way one gets exactly what they want is by doing it themselves.
Hence, yet another Prelude. But, the "yet another x" naming convention has run its course in my mind, so this was not going to be Yaprelude, Yalude, or anything of the sorts. Instead, wordplay of the prefix "Pre-". Thus: Ante-lude.
Important changes! #
Here's a good chunk of notable changes:
(.)is not natively available in Antelude, allowing for clarity when using the OverloadedRecordDot language extension. If you need the backwards-function-composition behavior of Prelude's(.), see(<.)(and its forwards-pointed counterpart,(.>))($)is not natively available in Antelude. Please see(<|)(and its forward-pointed counterpart(|>))- Antelude's
((<|), (|>))is not the same as inData.Sequence.Antelude.Sequencegives these symbols textual function names in case you were looking to useData.Sequence.((<|), (|>)).
- Antelude's
(++)is not natively available in Antelude. It's only purpose is to concatonate two lists, which(<>)can also do. If(<>)is not sufficient,Antelude.List.combineis defined as(Data.List.++)- I have identified an issue when using cabal's
Paths_modules. To remedy this, you can use the "making your own Prelude" method below (Installing/Using), importingData.List.(++)and exposing it.
- I have identified an issue when using cabal's
Antelude.Bool.(all, any)are equivalent toPrelude.(and, or). However,Antelude.List.(all, any)are the same asPrelude.(all, any).Antelude.List.(head, tail, init, last)return Maybe's and are safe for use. You can get the original ones fromData.List, but you shouldn't.fst, sndare not available.Tuples.Pairhasfirst, second, andTuples.Triohasfirst, second, third, as well as other Tuple tools for their bunch. If you really needfst, sndinstead of their full-name counterparts, get them from Data.Tuple- Almost everything has been moved into some Antelude module. Please take a look to see where to find what you were expecting to be in the global scope.
I purposely tried to restrict what is in the global scope. Most items are contained within Antelude.___ modules, or should be found from their native Data/Control.___ modules. This is an all inclusive list of functions that are in the global scope:
(|>)* |
(<|)* |
(.>) |
(<.) |
(<$>) |
(<&>) |
(<*>) |
(<*) |
(*>) |
(<|>) |
(<>) |
($!) |
(<$) |
($>) |
(&&) |
(||) |
(:|) |
(+) |
(-) |
(*) |
(**) |
(/) |
(^) |
(^^) |
(>) |
(<) |
(>=) |
(<=) |
(==) |
(/=) |
(>>=) |
(=<<) |
(>>) |
(<<) |
(>=>) |
(<=<) |
fmap |
liftA2 |
empty |
liftIO |
show |
showList |
print |
otherwise |
pure |
return |
*Notes:
- Remember,
(<|), (|>)are not the same as fromData.Sequence.
...as well as the following types:
Bool(..) |
Char |
String |
Int |
Integer |
Float |
Double |
Rational |
Word |
List a* |
NonEmpty a |
Array i a |
Pair a b* |
Trio a b c* |
Seq a |
Text* |
TextLazy* |
ByteString* |
ByteStringLazy* |
Set a |
Map a b* |
MapLazy a b* |
Maybe(..) |
Either(..) |
Result(..) |
Ordering(..) |
ShowS |
ReadS a |
IO a |
IOError |
FilePath |
Void |
*Notes:
List ais just an alias to[a]- base 4.21 now has this same alias.
- I'll have to figure out how to use that one and not ours so it works.
Pair a bis just an alias to(a, b)Trio a b cis just an alias to(a, b, c)Textis equivalent toData.Text (Text)TextLazyis equivalent toData.Text.Lazy (Text)ByteStringis equivalent toData.ByteString (ByteString)ByteStringLazyis equivalent toData.ByteString.Lazy (ByteString)Map a bis equivalent toData.Map.Strict (Map)MapLazy a bis equivalent toData.Map (Map)
...and typeclasses (to see which methods are exported from these typeclasses, see the exposed functions table above):
Eq |
Ord |
Enum |
Bounded |
Num |
Real |
Integral |
Fractional |
Floating |
RealFrac |
RealFloat |
Semigroup |
Monoid |
Functor |
Applicative |
Alternative |
Monad |
MonadIO |
MonadPlus |
MonadFail |
Foldable |
Traversable |
Show |
Read |
I encourage qualified imports, or named imports at the very least, as it helps newer developers understand where something came from and also helps solve name-conflict issues.
Between 0.1.0 and 1.0.0, things may change. Most probably won't, but some might. We'll see.
To-Do's #
- Decide if INLINE-ing is needed or wanted, and if so, where.
- Decide if Antelude's modules feel "feature complete".
- Maybe making Antelude backwards-compatible, where reasonable.
Installing/Using #
All of these involve adding Antelude as a dependency. So start with that, then...
using Cabal mixins, you should be able to do this in your library/executable/etc:
mixins: base hiding (Prelude)
, antelude (Antelude as Prelude)
, antelude
stack's mixin version will be listed when I get this on Stackage, but it's something like found here
Or for a build-tool agnostic verison, you can try making your own Prelude.hs next to your Main.hs file:
app/ <- a directory you defined in "hs-source-dirs" where...
Main.hs <- your "main-is" file (if an executable).
Prelude.hs <- add this, then see Prelude snippet below.
yourProject.cabal
stack.yaml
module Prelude
( module Antelude
) where
import Antelude