1
1
mirror of https://github.com/sdiehl/wiwinwlh.git synced 2024-09-11 12:05:25 +03:00

Write more

This commit is contained in:
sdiehl 2020-01-05 17:36:05 +00:00
parent 781f0d5705
commit c2ef9a5b61

View File

@ -397,6 +397,8 @@ See:
Cabal New-Build
---------------
Nix-style Local Builds
```perl
new-build Compile targets within the project.
new-configure Add extra project configuration
@ -416,7 +418,11 @@ new-sdist Generate a source distribution file (.tar.gz).
Version Bounds
--------------
```text
All Haskell packages are supposed to following the [Package Versioning Policy](https://pvp.haskell.org/).
![](https://pvp.haskell.org/pvp-decision-tree.svg)
```perl
base >= 4.6 && <4.14,
array >= 0.4 && <0.6,
ghc-prim >= 0.3 && <0.6,
@ -978,8 +984,8 @@ Linux Packages
TODO
https://downloads.haskell.org/~debian/
https://launchpad.net/~hvr/+archive/ubuntu/ghc
[Debian Packages](https://downloads.haskell.org/~debian/)
[Debian PPA](https://launchpad.net/~hvr/+archive/ubuntu/ghc)
```bash
$ sudo add-apt-repository -y ppa:hvr/ghc
@ -993,11 +999,65 @@ Continuous Integration
[Travis CI with Cabal](https://github.com/haskell-CI/haskell-ci/blob/master/.travis.yml)
[Travis CI with Stack](https://docs.haskellstack.org/en/stable/travis_ci/)
[Circle CI with Cabal]
[Circle CI with Stack]
[Github Actions with Cabal]
[Github Actions with Stack]
See [haskell-ci]((https://github.com/haskell-CI/haskell-ci)
Modules
-------
A module consists of a set of imports and exports and when compiled generates an
interface which is linked against other Haskell modules. A module may reexport
symbols from other modules.
Modules dependency graphs optionally may by cyclic (i.e. they import symbols
from each other) through the use of a boot file, but this is often best avoided
if at all possible.
```haskell
import Data.List (nub, sort)
```
```haskell
import Data.List hiding (nub)
```
```haskell
import qualified Data.Map
```
```haskell
import qualified Data.Map as M
```
You may dump multiple modules into the same namespace so long as the symbols do
not clash.
```haskell
import qualified Data.Map as M
import qualified Data.Map.Strict as M
```
Algebraic Datatypes
-------------------
TODO
Records
-------
Records in Haskell are fundamentally broken and there multiple philosophies
about how to round around this issue.
TODO RANT
Newtypes
--------
TODO
Bottoms
@ -1772,8 +1832,8 @@ In other words, the only path to understanding monads is to read the fine
source, fire up GHC, and write some code. Analogies and metaphors will not lead
to understanding.
Monadic Myths
-------------
Monad Myths
-----------
The following are all **false**:
@ -1790,8 +1850,8 @@ The following are all **false**:
See: [What a Monad Is Not](http://wiki.haskell.org/What_a_Monad_is_not)
Monadic Methods
---------------
Monad Methods
-------------
Monads are not complicated. They are implemented as a typeclass with two
methods, ``return`` and ``(>>=)`` (pronounced "bind"). In order to implement
@ -1833,8 +1893,8 @@ with types ``m a`` and ``m b`` respectively, while the infix returns a value of
type ``m b``. The actual implementation of (>>) says that when ``m`` is passed
to ``(>>)`` with ``k`` on the right, the value ``k`` will always be returned.
Laws
----
Monad Laws
----------
In addition to specific implementations of ``(>>=)`` and ``return``, all monad
instances must satisfy three laws.
@ -2870,16 +2930,16 @@ say that these extensions are benign and are safely used extensively:
* FlexibleContexts
* FlexibleInstances
* GeneralizedNewtypeDeriving
* TypeSynonymInstances
* MultiParamTypeClasses
* FunctionalDependencies
* NoMonomorphismRestriction
* GADTs
* [TypeSynonymInstances]
* [MultiParamTypeClasses](MultiParam Typeclasses)
* [FunctionalDependencies](MultiParam Typeclasses)
* [NoMonomorphismRestriction](Monomorphism Restriction)
* [GADTs]
* [BangPatterns]
* DeriveGeneric
* DeriveAnyClass
* DerivingStrategies
* ScopedTypeVariables
* [DeriveGeneric]
* [DeriveAnyClass]
* [DerivingStrategies]
* [ScopedTypeVariables](Scoped Type Variables)
The Advanced
------------
@ -3528,6 +3588,11 @@ DerivingStrategies
TODO
TypeInType
----------
TODO
Historical Extensions
---------------------
@ -4176,6 +4241,34 @@ readNote :: Read a => String -> String -> a
atNote :: String -> [a] -> Int -> a
```
A list of partial functions in the default prelude:
* error
* undefined
* fail
* head
* init
* tail
* last
* foldl
* foldr
* foldl'
* foldr'
* foldr1
* foldl1
* cycle
* maximum
* minimum
* (!!)
* sum
* product
* fromJust
* read
* reverse
* toEnum
* genericIndex
* (!)
Boolean Blindness
------------------
@ -4583,20 +4676,6 @@ See:
* [Bytestring: Bits and Pieces](https://www.schoolofhaskell.com/school/to-infinity-and-beyond/pick-of-the-week/bytestring-bits-and-pieces)
* [ByteString](http://hackage.haskell.org/package/bytestring-0.10.4.0/docs/Data-ByteString.html)
utf8-string
-----------
TODO
See: [utf8-string](https://hackage.haskell.org/package/utf8-string)
base64-bytestring
-----------
TODO
See: [utf8-string](https://hackage.haskell.org/package/base64-bytestring)
Printf
------
@ -4605,6 +4684,11 @@ Haskell also has a variadic ``printf`` function in the style of C.
~~~~ {.haskell include="src/07-text-bytestring/printf.hs"}
~~~~
Pretty Simple
-------------
TODO
Overloaded Lists
----------------
@ -5046,6 +5130,17 @@ See:
* [Control.Monad.Except](https://hackage.haskell.org/package/mtl-2.2.1/docs/Control-Monad-Except.html)
exceptions
----------
TODO
* MonadThrow
* MonadCatch
* MonadMask
https://hackage.haskell.org/package/exceptions
spoon
-----
@ -5067,6 +5162,7 @@ See:
* [Spoon](https://hackage.haskell.org/package/spoon)
<hr/>
Advanced Monads
@ -5417,7 +5513,7 @@ Normally quantifiers are omitted in type signatures since in Haskell's vanilla
surface language it is unambiguous to assume to that free type variables are
universally quantified.
Free theorems
Free Theorems
-------------
A universally quantified type-variable actually implies quite a few rather deep
@ -7687,6 +7783,198 @@ sections:
* GHC.Generics
* generics-sop
Generic
-------
The most modern method of doing generic programming uses type families to
achieve a better method of deriving the structural properties of arbitrary type
classes. Generic implements a typeclass with an associated type ``Rep`` (
Representation ) together with a pair of functions that form a 2-sided inverse (
isomorphism ) for converting to and from the associated type and the derived
type in question.
```haskell
class Generic a where
type Rep a
from :: a -> Rep a
to :: Rep a -> a
class Datatype d where
datatypeName :: t d f a -> String
moduleName :: t d f a -> String
class Constructor c where
conName :: t c f a -> String
```
[GHC.Generics](https://www.haskell.org/ghc/docs/7.4.1/html/libraries/ghc-prim-0.2.0.0/GHC-Generics.html)
defines a set of named types for modeling the various structural properties of
types in available in Haskell.
```haskell
-- | Sums: encode choice between constructors
infixr 5 :+:
data (:+:) f g p = L1 (f p) | R1 (g p)
-- | Products: encode multiple arguments to constructors
infixr 6 :*:
data (:*:) f g p = f p :*: g p
-- | Tag for M1: datatype
data D
-- | Tag for M1: constructor
data C
-- | Constants, additional parameters and recursion of kind *
newtype K1 i c p = K1 { unK1 :: c }
-- | Meta-information (constructor names, etc.)
newtype M1 i c f p = M1 { unM1 :: f p }
-- | Type synonym for encoding meta-information for datatypes
type D1 = M1 D
-- | Type synonym for encoding meta-information for constructors
type C1 = M1 C
```
Using the deriving mechanics GHC can generate this Generic instance for us
mechanically, if we were to write it by hand for a simple type it might look
like this:
~~~~ {.haskell include="src/18-generics/generics.hs"}
~~~~
Use ``kind!`` in GHCi we can look at the type family ``Rep`` associated with a Generic instance.
```haskell
λ: :kind! Rep Animal
Rep Animal :: * -> *
= M1 D T_Animal (M1 C C_Dog U1 :+: M1 C C_Cat U1)
λ: :kind! Rep ()
Rep () :: * -> *
= M1 D GHC.Generics.D1() (M1 C GHC.Generics.C1_0() U1)
λ: :kind! Rep [()]
Rep [()] :: * -> *
= M1
D
GHC.Generics.D1[]
(M1 C GHC.Generics.C1_0[] U1
:+: M1
C
GHC.Generics.C1_1[]
(M1 S NoSelector (K1 R ()) :*: M1 S NoSelector (K1 R [()])))
```
Now the clever bit, instead writing our generic function over the datatype we
instead write it over the Rep and then reify the result using ``from``. So for
an equivalent version of Haskell's default ``Eq`` that instead uses generic
deriving we could write:
```haskell
class GEq' f where
geq' :: f a -> f a -> Bool
instance GEq' U1 where
geq' _ _ = True
instance (GEq c) => GEq' (K1 i c) where
geq' (K1 a) (K1 b) = geq a b
instance (GEq' a) => GEq' (M1 i c a) where
geq' (M1 a) (M1 b) = geq' a b
-- Equality for sums.
instance (GEq' a, GEq' b) => GEq' (a :+: b) where
geq' (L1 a) (L1 b) = geq' a b
geq' (R1 a) (R1 b) = geq' a b
geq' _ _ = False
-- Equality for products.
instance (GEq' a, GEq' b) => GEq' (a :*: b) where
geq' (a1 :*: b1) (a2 :*: b2) = geq' a1 a2 && geq' b1 b2
```
To accommodate the two methods of writing classes (generic-deriving or
custom implementations) we can use the ``DefaultSignatures`` extension to allow the
user to leave typeclass functions blank and defer to Generic or to define
their own.
```haskell
{-# LANGUAGE DefaultSignatures #-}
class GEq a where
geq :: a -> a -> Bool
default geq :: (Generic a, GEq' (Rep a)) => a -> a -> Bool
geq x y = geq' (from x) (from y)
```
Now anyone using our library need only derive Generic and create an empty
instance of our typeclass instance without writing any boilerplate for ``GEq``.
Here is a complete example for deriving equality generics:
~~~~ {.haskell include="src/18-generics/generic_impl.hs"}
~~~~
See:
* [Cooking Classes with Datatype Generic Programming](http://www.stephendiehl.com/posts/generics.html)
* [Datatype-generic Programming in Haskell](http://www.andres-loeh.de/DGP-Intro.pdf)
* [generic-deriving](http://hackage.haskell.org/package/generic-deriving-1.6.3)
Generic Deriving
----------------
Using Generics many common libraries provide a mechanisms to derive common
typeclass instances. Some real world examples:
The [hashable](http://hackage.haskell.org/package/hashable) library allows us to
derive hashing functions.
~~~~ {.haskell include="src/18-generics/hashable.hs"}
~~~~
The [cereal](http://hackage.haskell.org/package/cereal-0.4.0.1) library allows
us to automatically derive a binary representation.
~~~~ {.haskell include="src/18-generics/cereal.hs"}
~~~~
The [aeson](http://hackage.haskell.org/package/aeson) library allows us to
derive JSON representations for JSON instances.
~~~~ {.haskell include="src/18-generics/derive_aeson.hs"}
~~~~
See: [A Generic Deriving Mechanism for Haskell](http://dreixel.net/research/pdf/gdmh.pdf)
##### Higher Kinded Generics
Using the same interface GHC.Generics provides a separate typeclass for
higher-kinded generics.
```haskell
class Generic1 f where
type Rep1 f :: * -> *
from1 :: f a -> (Rep1 f) a
to1 :: (Rep1 f) a -> f a
```
So for instance ``Maybe`` has ``Rep1`` of the form:
```haskell
type instance Rep1 Maybe
= D1
GHC.Generics.D1Maybe
(C1 C1_0Maybe U1
:+: C1 C1_1Maybe (S1 NoSelector Par1))
```
Typeable
--------
@ -7885,202 +8173,6 @@ example2 = numHoles (Just 3)
-- 1
```
Generic
-------
The most modern method of doing generic programming uses type families to
achieve a better method of deriving the structural properties of arbitrary type
classes. Generic implements a typeclass with an associated type ``Rep`` (
Representation ) together with a pair of functions that form a 2-sided inverse (
isomorphism ) for converting to and from the associated type and the derived
type in question.
```haskell
class Generic a where
type Rep a
from :: a -> Rep a
to :: Rep a -> a
class Datatype d where
datatypeName :: t d f a -> String
moduleName :: t d f a -> String
class Constructor c where
conName :: t c f a -> String
```
[GHC.Generics](https://www.haskell.org/ghc/docs/7.4.1/html/libraries/ghc-prim-0.2.0.0/GHC-Generics.html)
defines a set of named types for modeling the various structural properties of
types in available in Haskell.
```haskell
-- | Sums: encode choice between constructors
infixr 5 :+:
data (:+:) f g p = L1 (f p) | R1 (g p)
-- | Products: encode multiple arguments to constructors
infixr 6 :*:
data (:*:) f g p = f p :*: g p
-- | Tag for M1: datatype
data D
-- | Tag for M1: constructor
data C
-- | Constants, additional parameters and recursion of kind *
newtype K1 i c p = K1 { unK1 :: c }
-- | Meta-information (constructor names, etc.)
newtype M1 i c f p = M1 { unM1 :: f p }
-- | Type synonym for encoding meta-information for datatypes
type D1 = M1 D
-- | Type synonym for encoding meta-information for constructors
type C1 = M1 C
```
Using the deriving mechanics GHC can generate this Generic instance for us
mechanically, if we were to write it by hand for a simple type it might look
like this:
~~~~ {.haskell include="src/18-generics/generics.hs"}
~~~~
Use ``kind!`` in GHCi we can look at the type family ``Rep`` associated with a Generic instance.
```haskell
λ: :kind! Rep Animal
Rep Animal :: * -> *
= M1 D T_Animal (M1 C C_Dog U1 :+: M1 C C_Cat U1)
λ: :kind! Rep ()
Rep () :: * -> *
= M1 D GHC.Generics.D1() (M1 C GHC.Generics.C1_0() U1)
λ: :kind! Rep [()]
Rep [()] :: * -> *
= M1
D
GHC.Generics.D1[]
(M1 C GHC.Generics.C1_0[] U1
:+: M1
C
GHC.Generics.C1_1[]
(M1 S NoSelector (K1 R ()) :*: M1 S NoSelector (K1 R [()])))
```
Now the clever bit, instead writing our generic function over the datatype we
instead write it over the Rep and then reify the result using ``from``. So for
an equivalent version of Haskell's default ``Eq`` that instead uses generic
deriving we could write:
```haskell
class GEq' f where
geq' :: f a -> f a -> Bool
instance GEq' U1 where
geq' _ _ = True
instance (GEq c) => GEq' (K1 i c) where
geq' (K1 a) (K1 b) = geq a b
instance (GEq' a) => GEq' (M1 i c a) where
geq' (M1 a) (M1 b) = geq' a b
-- Equality for sums.
instance (GEq' a, GEq' b) => GEq' (a :+: b) where
geq' (L1 a) (L1 b) = geq' a b
geq' (R1 a) (R1 b) = geq' a b
geq' _ _ = False
-- Equality for products.
instance (GEq' a, GEq' b) => GEq' (a :*: b) where
geq' (a1 :*: b1) (a2 :*: b2) = geq' a1 a2 && geq' b1 b2
```
To accommodate the two methods of writing classes (generic-deriving or
custom implementations) we can use the ``DefaultSignatures`` extension to allow the
user to leave typeclass functions blank and defer to Generic or to define
their own.
```haskell
{-# LANGUAGE DefaultSignatures #-}
class GEq a where
geq :: a -> a -> Bool
default geq :: (Generic a, GEq' (Rep a)) => a -> a -> Bool
geq x y = geq' (from x) (from y)
```
Now anyone using our library need only derive Generic and create an empty
instance of our typeclass instance without writing any boilerplate for ``GEq``.
Here is a complete example for deriving equality generics:
~~~~ {.haskell include="src/18-generics/generic_impl.hs"}
~~~~
See:
* [Cooking Classes with Datatype Generic Programming](http://www.stephendiehl.com/posts/generics.html)
* [Datatype-generic Programming in Haskell](http://www.andres-loeh.de/DGP-Intro.pdf)
* [generic-deriving](http://hackage.haskell.org/package/generic-deriving-1.6.3)
Generic Deriving
----------------
Using Generics many common libraries provide a mechanisms to derive common
typeclass instances. Some real world examples:
The [hashable](http://hackage.haskell.org/package/hashable) library allows us to
derive hashing functions.
~~~~ {.haskell include="src/18-generics/hashable.hs"}
~~~~
The [cereal](http://hackage.haskell.org/package/cereal-0.4.0.1) library allows
us to automatically derive a binary representation.
~~~~ {.haskell include="src/18-generics/cereal.hs"}
~~~~
The [aeson](http://hackage.haskell.org/package/aeson) library allows us to
derive JSON representations for JSON instances.
~~~~ {.haskell include="src/18-generics/derive_aeson.hs"}
~~~~
See: [A Generic Deriving Mechanism for Haskell](http://dreixel.net/research/pdf/gdmh.pdf)
##### Higher Kinded Generics
Using the same interface GHC.Generics provides a separate typeclass for
higher-kinded generics.
```haskell
class Generic1 f where
type Rep1 f :: * -> *
from1 :: f a -> (Rep1 f) a
to1 :: (Rep1 f) a -> f a
```
So for instance ``Maybe`` has ``Rep1`` of the form:
```haskell
type instance Rep1 Maybe
= D1
GHC.Generics.D1Maybe
(C1 C1_0Maybe U1
:+: C1 C1_1Maybe (S1 NoSelector Par1))
```
generics-sop
------------
TODO
Uniplate
--------
@ -8944,6 +9036,36 @@ example f x y = runEval $ do
return (a, b)
```
Threads
-------
TODO
IORef
-----
TODO
MVars
-----
TODO
TVar
----
TODO
Chans
-----
TODO
Semaphores
----------
TODO
Threadscope
-----------
@ -9493,18 +9615,14 @@ cryptonite
----------
Cryptonite is the standard Haskell cryptography library. It provides support for
hash functions, elliptic curve cryptography, ciphers, one time passwords and
safe memory handling.
hash functions, elliptic curve cryptography, ciphers, one time passwords,
entropy generation and safe memory handling.
* AES
* Blowfish
* Camellia
* ChaCha
* ChaChaPoly1305
* **DES**
* **RC4**
* Salsa
* TripleDES
* Ed25519
* Curve25519
* Blake2
* Argon2
**Hashing**
@ -9567,6 +9685,11 @@ TODO
Date and Time
=============
time
----
TODO
hourglass
---------
@ -9876,6 +9999,11 @@ most flexible is the [HTTP library](https://hackage.haskell.org/package/HTTP).
~~~~ {.haskell include="src/27-web/http.hs"}
~~~~
Req
---
TODO
Blaze
-----
@ -9930,6 +10058,16 @@ Servant
TODO
Swagger
-------
TODO
GraphQL
-------
TODO
Hastache
--------
@ -10275,6 +10413,16 @@ main = do
putStrLn $ showSDoc ( ppr res )
```
Abstract Syntax Tree
--------------------
TODO
Parser
------
TODO
Outputable
----------
@ -12015,8 +12163,8 @@ There are many many many pretty printing libraries for Haskell.
* layout
* aeson-pretty
pretty
------
prettyprinter
-------------
Pretty is the first Wadler-Leijen style combinator library, it exposes a simple
set of primitives to print Haskell datatypes to legacy strings pro
@ -12057,32 +12205,6 @@ import Text.Show.Pretty (ppShow)
let pprint x = putStrLn $ ppShow x
```
See:
* [The Design of a Pretty-printing Library](http://belle.sourceforge.net/doc/hughes95design.pdf)
wl-pprint-text
--------------
``wl-pprint-text`` is a Wadler-style pretty printing library that uses Text
builder objects for efficient generation under the hood. It exposes effectively
the same interface as the String-based ``pretty`` library but is much more
performant.
##### Combinators
```haskell
renderPretty :: Float -> Int -> Doc -> SimpleDoc
renderCompact :: Doc -> SimpleDoc
renderOneLine :: Doc -> SimpleDoc
```
See:
#### Monadic API
* [wl-pprint-text](https://hackage.haskell.org/package/wl-pprint-text)
pretty-show
-----------