1
1
mirror of https://github.com/sdiehl/wiwinwlh.git synced 2024-08-16 23:40:41 +03:00

reform pdf output & mmorph

This commit is contained in:
Stephen Diehl 2016-03-28 15:49:49 -04:00
parent 2b136ee576
commit d364c9021c
11 changed files with 381 additions and 29 deletions

1
.gitignore vendored
View File

@ -11,3 +11,4 @@ includes
*.epub
*.agdai
.stack-work
tutorial.pdf

View File

@ -2,6 +2,7 @@ PANDOC = pandoc
IFORMAT = markdown
FLAGS = --standalone --toc --toc-depth=2 --highlight-style pygments
TEMPLATE = resources/page.tmpl
LTEMPLATE = resources/page.latex
STYLE = css/style.css
HTML = tutorial.html
@ -27,7 +28,7 @@ includes: includes.hs
./includes < $< | $(PANDOC) -f $(IFORMAT) -t epub $(FLAGS) -o $@
%.pdf: %.md includes
./includes < $< | $(PANDOC) -c -s -f $(IFORMAT) --latex-engine=xelatex $(FLAGS) -o $@
./includes < $< | $(PANDOC) -c -s -f $(IFORMAT) --template $(LTEMPLATE) --latex-engine=xelatex $(FLAGS) -o $@
clean:
-rm $(CHAPTERS) $(HTML)

View File

@ -12,7 +12,7 @@ Real Online:
* [**HTML**](http://dev.stephendiehl.com/hask/)
* [**Example Code**](https://github.com/sdiehl/wiwinwlh/tree/master/src)
Examples:
Chapter Code Examples:
* [01-basics/ ](https://github.com/sdiehl/wiwinwlh/tree/master/src/01-basics/)
* [02-monads/ ](https://github.com/sdiehl/wiwinwlh/tree/master/src/02-monads/)

270
resources/page.latex Normal file
View File

@ -0,0 +1,270 @@
\documentclass[$if(fontsize)$$fontsize$,$endif$$if(lang)$$babel-lang$,$endif$$if(papersize)$$papersize$paper,$endif$$for(classoption)$$classoption$$sep$,$endfor$]{$documentclass$}
$if(fontfamily)$
\usepackage[$for(fontfamilyoptions)$$fontfamilyoptions$$sep$,$endfor$]{$fontfamily$}
$else$
\usepackage{lmodern}
$endif$
$if(linestretch)$
\usepackage{setspace}
\setstretch{$linestretch$}
$endif$
\usepackage{amssymb,amsmath}
\usepackage{ifxetex,ifluatex}
\usepackage{fixltx2e} % provides \textsubscript
\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
\usepackage[$if(fontenc)$$fontenc$$else$T1$endif$]{fontenc}
\usepackage[utf8]{inputenc}
$if(euro)$
\usepackage{eurosym}
$endif$
\else % if luatex or xelatex
\ifxetex
\usepackage{mathspec}
\else
\usepackage{fontspec}
\fi
\defaultfontfeatures{Ligatures=TeX,Scale=MatchLowercase}
$if(euro)$
\newcommand{\euro}{€}
$endif$
$if(mainfont)$
\setmainfont[$for(mainfontoptions)$$mainfontoptions$$sep$,$endfor$]{$mainfont$}
$endif$
$if(sansfont)$
\setsansfont[$for(sansfontoptions)$$sansfontoptions$$sep$,$endfor$]{$sansfont$}
$endif$
$if(monofont)$
\setmonofont[Mapping=tex-ansi$if(monofontoptions)$,$for(monofontoptions)$$monofontoptions$$sep$,$endfor$$endif$]{$monofont$}
$endif$
$if(mathfont)$
\setmathfont(Digits,Latin,Greek)[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$}
$endif$
$if(CJKmainfont)$
\usepackage{xeCJK}
\setCJKmainfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmainfont$}
$endif$
\fi
% use upquote if available, for straight quotes in verbatim environments
\IfFileExists{upquote.sty}{\usepackage{upquote}}{}
% use microtype if available
\IfFileExists{microtype.sty}{%
\usepackage{microtype}
\UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts
}{}
$if(geometry)$
\usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry}
$endif$
\usepackage{hyperref}
$if(colorlinks)$
\PassOptionsToPackage{usenames,dvipsnames}{color} % color is loaded by hyperref
$endif$
\hypersetup{unicode=true,
$if(title-meta)$
pdftitle={$title-meta$},
$endif$
$if(author-meta)$
pdfauthor={$author-meta$},
$endif$
$if(keywords)$
pdfkeywords={$for(keywords)$$keywords$$sep$; $endfor$},
$endif$
$if(colorlinks)$
colorlinks=true,
linkcolor=$if(linkcolor)$$linkcolor$$else$Maroon$endif$,
citecolor=$if(citecolor)$$citecolor$$else$Blue$endif$,
urlcolor=$if(urlcolor)$$urlcolor$$else$Blue$endif$,
$else$
pdfborder={0 0 0},
$endif$
breaklinks=true}
\urlstyle{same} % don't use monospace font for urls
$if(lang)$
\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
\usepackage[shorthands=off,$for(babel-otherlangs)$$babel-otherlangs$,$endfor$main=$babel-lang$]{babel}
$if(babel-newcommands)$
$babel-newcommands$
$endif$
\else
\usepackage{polyglossia}
\setmainlanguage[$polyglossia-lang.options$]{$polyglossia-lang.name$}
$for(polyglossia-otherlangs)$
\setotherlanguage[$polyglossia-otherlangs.options$]{$polyglossia-otherlangs.name$}
$endfor$
\fi
$endif$
$if(natbib)$
\usepackage{natbib}
\bibliographystyle{$if(biblio-style)$$biblio-style$$else$plainnat$endif$}
$endif$
$if(biblatex)$
\usepackage$if(biblio-style)$[style=$biblio-style$]$endif${biblatex}
$if(biblatexoptions)$\ExecuteBibliographyOptions{$for(biblatexoptions)$$biblatexoptions$$sep$,$endfor$}$endif$
$for(bibliography)$
\addbibresource{$bibliography$}
$endfor$
$endif$
$if(listings)$
\usepackage{listings}
$endif$
$if(lhs)$
\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{}
$endif$
$if(highlighting-macros)$
$highlighting-macros$
$endif$
$if(verbatim-in-note)$
\usepackage{fancyvrb}
\VerbatimFootnotes % allows verbatim text in footnotes
$endif$
$if(tables)$
\usepackage{longtable,booktabs}
$endif$
$if(graphics)$
\usepackage{graphicx,grffile}
\makeatletter
\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi}
\def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi}
\makeatother
% Scale images if necessary, so that they will not overflow the page
% margins by default, and it is still possible to overwrite the defaults
% using explicit options in \includegraphics[width, height, ...]{}
\setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio}
$endif$
$if(links-as-notes)$
% Make links footnotes instead of hotlinks:
\renewcommand{\href}[2]{#2\footnote{\url{#1}}}
$endif$
$if(strikeout)$
\usepackage[normalem]{ulem}
% avoid problems with \sout in headers with hyperref:
\pdfstringdefDisableCommands{\renewcommand{\sout}{}}
$endif$
$if(indent)$
$else$
\IfFileExists{parskip.sty}{%
\usepackage{parskip}
}{% else
\setlength{\parindent}{0pt}
\setlength{\parskip}{6pt plus 2pt minus 1pt}
}
$endif$
\setlength{\emergencystretch}{3em} % prevent overfull lines
\providecommand{\tightlist}{%
\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
$if(numbersections)$
\setcounter{secnumdepth}{5}
$else$
\setcounter{secnumdepth}{0}
$endif$
$if(subparagraph)$
$else$
% Redefines (sub)paragraphs to behave more like sections
\ifx\paragraph\undefined\else
\let\oldparagraph\paragraph
\renewcommand{\paragraph}[1]{\oldparagraph{#1}\mbox{}}
\fi
\ifx\subparagraph\undefined\else
\let\oldsubparagraph\subparagraph
\renewcommand{\subparagraph}[1]{\oldsubparagraph{#1}\mbox{}}
\fi
$endif$
$if(dir)$
\ifxetex
% load bidi as late as possible as it modifies e.g. graphicx
$if(latex-dir-rtl)$
\usepackage[RTLdocument]{bidi}
$else$
\usepackage{bidi}
$endif$
\fi
\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
\TeXXeTstate=1
\newcommand{\RL}[1]{\beginR #1\endR}
\newcommand{\LR}[1]{\beginL #1\endL}
\newenvironment{RTL}{\beginR}{\endR}
\newenvironment{LTR}{\beginL}{\endL}
\fi
$endif$
$for(header-includes)$
$header-includes$
$endfor$
$if(title)$
\title{$title$$if(thanks)$\thanks{$thanks$}$endif$}
$endif$
$if(subtitle)$
\providecommand{\subtitle}[1]{}
\subtitle{$subtitle$}
$endif$
$if(author)$
\author{$for(author)$$author$$sep$ \and $endfor$}
$endif$
$if(institute)$
\institute{$for(institute)$$institute$$sep$ \and $endfor$}
$endif$
\date{$date$}
\begin{document}
\begin{titlepage}
\vspace*{\stretch{1.0}}
\begin{center}
\Large\textbf{What I Wish I Knew When Learning Haskell}\\
\large\textit{Stephen Diehl}
\end{center}
\vspace*{\stretch{2.0}}
\end{titlepage}
$if(abstract)$
\begin{abstract}
$abstract$
\end{abstract}
$endif$
$for(include-before)$
$include-before$
$endfor$
$if(toc)$
{
$if(colorlinks)$
\hypersetup{linkcolor=$if(toccolor)$$toccolor$$else$black$endif$}
$endif$
\setcounter{tocdepth}{$toc-depth$}
\tableofcontents
\newpage
}
$endif$
$if(lot)$
\listoftables
$endif$
$if(lof)$
\listoffigures
$endif$
$body$
$if(natbib)$
$if(bibliography)$
$if(biblio-title)$
$if(book-class)$
\renewcommand\bibname{$biblio-title$}
$else$
\renewcommand\refname{$biblio-title$}
$endif$
$endif$
\bibliography{$for(bibliography)$$bibliography$$sep$,$endfor$}
$endif$
$endif$
$if(biblatex)$
\printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$
$endif$
$for(include-after)$
$include-after$
$endfor$
\end{document}

View File

@ -2,4 +2,9 @@ Basics
======
```bash
$ stack exec ghci bottoms.hs
$ stack exec ghci defer.hs
$ stack exec ghci fail.hs
$ stack exec ghci stacktrace.hs
$ stack exec ghci trace.hs
```

View File

@ -3,4 +3,5 @@ Prelude
```bash
$ stack exec ghci split.hs
$ stack exec ghci foldable_traversable.hs
```

View File

@ -11,8 +11,10 @@ tested-with: GHC == 7.6.3
library
build-depends:
mmorph >= 1.0 && <1.1,
mtl >= 2.2 && <2.3,
base >= 4.6 && <4.10
safe >= 0.3 && <0.4,
mmorph >= 1.0 && <1.1,
mtl >= 2.2 && <2.3,
transformers-base >= 0.4 && <0.5,
base >= 4.6 && <4.10
default-language: Haskell2010

View File

@ -1,5 +1,5 @@
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
import Data.IORef

View File

@ -1,2 +1,28 @@
import Control.Monad.Trans
import Control.Monad.State
import Control.Monad.Morph
type Eval a = State [Int] a
runEval :: [Int] -> Eval a -> a
runEval = flip evalState
pop :: Eval Int
pop = do
top <- gets head
modify tail
return top
push :: Int -> Eval ()
push x = modify (x:)
ev1 :: Eval Int
ev1 = do
push 3
push 4
pop
pop
ev2 :: StateT [Int] IO ()
ev2 = do
result <- hoist generalize ev1
liftIO $ putStrLn $ "Result: " ++ show result

View File

@ -11,4 +11,5 @@ Parsing
$ stack exec ghci parsec_operators.hs
$ stack exec ghci parser.hs
$ stack exec ghci simple_parser.hs
$ stack exec ghci configurator.hs
```

View File

@ -1,6 +1,6 @@
<p class="center logo">
![](img/title.png)
</p>
% What I Wish I Knew When Learning Haskell
% Stephen Diehl
% March 2016
Stephen Diehl (<a class="author" href="https://twitter.com/smdiehl">@smdiehl</a> )
@ -2040,17 +2040,47 @@ forM_ xs (lift . f) == lift (forM_ xs f)
Monad Morphisms
---------------
The base monad transformer package provides a ``MonadTrans`` class for lifting
between layer:
```haskell
lift :: Monad m => m a -> t m a
```
But often times we need to work with and manipulate our monad transformer stack
to either produce new transformers, modify existing ones, or extend an upstream
library with new layers. The ``mmorph`` library provides the capacity to compose
monad morphism transformation directly on transformer stacks. The equivalent of
type transformer type-level map is the ``hoist`` function.
```haskell
hoist :: Monad m => (forall a. m a -> n a) -> t m b -> t n b
embed :: Monad n => (forall a. m a -> t n a) -> t m b -> t n b
squash :: (Monad m, MMonad t) => t (t m) a -> t m a
```
TODO
Hoist takes a *monad morphism* (a mapping a ``m a`` to a ``n a``) and applies in
on the inner value monad of a transformer stack, transforming the value under
the outer layer.
For example the monad morphism ``generalize`` takes an Identity into another
monad ``m`` of the same index. For example this generalizes ``State s Identity``
into ``StateT s m a``.
```haskell
generalize :: Monad m => Identity a -> m a
```
So we could generalize an existing transformer to lift a IO layer into it.
~~~~ {.haskell include="src/10-advanced-monads/mmorph.hs"}
~~~~
```haskell
embed :: Monad n => (forall a. m a -> t n a) -> t m b -> t n b
```
```haskell
squash :: (Monad m, MMonad t) => t (t m) a -> t m a
```
See: [mmorph](https://hackage.haskell.org/package/mmorph)
@ -3018,10 +3048,31 @@ f $! x = let !vx = x in f vx
Strict Haskell
--------------
#### Strict
As of GHC 8.0
#### StrictData
Enabling StrictData makes constructor fields strict by default on any module it
is enabled on.
```haskell
data Employee = Employee
{ name :: T.Text
, age :: Int
}
```
```
data Employee = Employee
{ name :: !T.Text
, age :: !Int
}
```
#### Strict
Strict implies ``-XStrictData``
Deepseq
-------
@ -3130,7 +3181,6 @@ To get work done you probably need.
* async
* bytestring
* containers
* exceptions
* mtl
* stm
* text
@ -5039,16 +5089,14 @@ See:
Final Interpreters
------------------
TODO
Using typeclasses we can implement a *final interpreter* which models a set of
extensible terms using functions bound to typeclasses rather than data
constructors. Instances of the typeclass form interpreters over these terms.
For example we can write a small language that includes basic arithmetic, and
then retroactively extend our expression language with a multiplication operator
without changing the base. At the same time our interpreter logic
remains invariant under extension with new expressions.
without changing the base. At the same time our interpreter logic remains
invariant under extension with new expressions.
~~~~ {.haskell include="src/14-interpreters/fext.hs"}
~~~~
@ -6581,12 +6629,8 @@ compiler, it can't automatically deduce the isomorphism between natural numbers
and Peano numbers.
So at each of these call sites we now have a proof obligation to construct proof
terms which rearrange the type signatures of the terms in question such that
actual types in the error messages GHC gave us align with the expected values to
complete the program.
Recall from our discussion of propositional equality from GADTs that we actually have such machinery to do
this!
terms. Recall from our discussion of propositional equality from GADTs that we
actually have such machinery to construct this now.
~~~~ {.haskell include="src/17-promotion/reverse.hs"}
~~~~
@ -7117,10 +7161,11 @@ See:
Generic Deriving
----------------
Using Generics, we can ask GHC to do lots of non-trivial code generation which
works spectacularly well in practice. Some real world examples:
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.
The [hashable](http://hackage.haskell.org/package/hashable) library allows us to
derive hashing functions.
~~~~ {.haskell include="src/18-generics/hashable.hs"}
~~~~
@ -11570,7 +11615,7 @@ ver = showVersion Paths_myprog.version
See: [git-embed](https://hackage.haskell.org/package/git-embed)
</hr>
<hr/>
Categories
==========