Info on some haskell packages.
- Hedgehog
- Megaparsec
- Lens
- and more
Hedgehog
Property: Invariants that would be tested fuzzilyGen a: Generator for random values of atype Gen = GenT Identity
MonadGen: Class of monads which can generate input data for tests- Get samples:
Gen.sample
See:
- https://hackage.haskell.org/package/hedgehog-1.5/docs/Hedgehog.html
- https://hackage.haskell.org/package/hedgehog-1.5/docs/Hedgehog-Gen.html
- https://hackage.haskell.org/package/hedgehog-1.5/docs/Hedgehog-Range.html
λ> :t G.int $ R.constant 0 10
G.int $ R.constant 0 10 :: MonadGen m => m Int
Megaparsec
Monad transformer: Think of it as a function taking a monad and returning another monad.
- ParsecT err inp m res: monad transformer
- err: err message type
- inp: input type
- m: inner monad
- res: result type
Parsec e inp res = ParsecT e inp Identity res
-- Parser res = Parsec Void Text res
type Parser = Parsec Void TextParser a means a parser whose result after successful parsing is of type a.
import Data.Void
-- +-- Input type
-- |
-- v
type Parser = Parsec Void Text
-- ^
-- |
-- Error componentInfo
Parsec: non-transformer version ofParsecT- Both are monads.
Functions
- satisfy: accept character if a condition is met
- between
- symbol
- sepBy1
- many
<|><*><$>
Operator table
- A nested list
- Items in the same level have equal precedence in the inner lists
- Elements that appear earlier in the outer list have more precedence
From https://markkarpov.com/tutorial/megaparsec.html:
data Operator m a
= InfixN (m (a -> a -> a)) -- ^ Non-associative infix
| InfixL (m (a -> a -> a)) -- ^ Left-associative infix
| InfixR (m (a -> a -> a)) -- ^ Right-associative infix
| Prefix (m (a -> a)) -- ^ Prefix
| Postfix (m (a -> a)) -- ^ PostfixSee:
- https://hackage.haskell.org/package/parser-combinators-1.3.0/docs/Control-Monad-Combinators-Expr.html
- https://hackage.haskell.org/package/megaparsec-5.2.0/docs/Text-Megaparsec-Expr.html (since removed from megaparsec)
Lens
https://hackage.haskell.org/package/lens-tutorial-1.0.5/docs/Control-Lens-Tutorial.html
- Accessor notation:
^.val^.attr.subattris likeobj.attr.subattrin Python- Same as val
val ^. (attr . subattr) ^.is same asview:x ^. l = view l x
- Cons:
- Error messages can be confusing
- Increased compile time. To generate lenses.
- Packages:
lens: lot of dependenciesmicrolensorlens-simple: light-weight form oflenswith fewer dependencies
—
%=:
- Apply a function to get new state
- https://hackage.haskell.org/package/lens-5.3.2/docs/Control-Lens-Operators.html#v:-37--61-
>>> execState (do _1 %= f;_2 %= g) (a,b)
(f a, g b)
>>> execState (do both %= f) (a,b)
(f a, f b).=:
- Assign a new state
>>> execState (do _1 .= c;_2 %= d) (a,b)
(c, d)
>>> execState (do both %= c) (a,b)
(c, c)—
More concepts:
- Traversal: getter-setters for a list of fields ??
- Prism
- Iso
- Review
Functions: re, unto, set, .=,
One possible use of lens: getters-setters when using nested record types
over: setterview: getter
It's like this:
data Lens a b = Lens
{ view :: a -> b
, over :: (b -> b) -> (a -> a)
}Create lens for a type with:
makeLenses ''<bigtype>
makeLenses ''<smalltype>
This is made possible with TemplateHaskell.
Field names in the record type should have underscore prefix.
Containers
Seq (as in list) type from Data.Sequence of 'containers' package.
<│ |
Add element to left end of a seq | a -> Seq a -> Seq a |
│> |
Add element to right end of a seq | a -> Seq a -> Seq a |
>< |
Concatenate two sequnces | Seq a -> Seq a -> Seq a |
Bricks
A package for making TUIs.
<+>: Vertical split<=>: Horizontal split- microlens is a dependency, so lens can be used
Timers can be made with BChan
- Docs: https://hackage.haskell.org/package/brick-2.4/docs/Brick-BChan.html
- Eg: https://github.com/jtdaugherty/brick/blob/master/programs/CustomEventDemo.hs
More:
Parsec
<?>:parser <?> err_msgerr_msgshown when parsing withparserfails
Darcs
Focus is on 'changes' rather than 'snapshots'.
- Init: darcs init
- Clone a repo: darcs clone ..
- Record (ie, commit): darcs record -m "commit message"
- Show untracked files: darcs whatsnew -l
- Show untracked changes in tracked files: darcs whatsnew
- Add a file to repo: darcs add <filename>
- Push: darcs push
- 'Uncommit' a record, while preserving working copy: darcs unrecord
–
Git analogues:
| git | darcs |
|---|---|
| commit | record |