Use typst for monads presentation
This commit is contained in:
parent
2031c13030
commit
60b7f9e152
5 changed files with 192 additions and 74 deletions
|
@ -1,11 +1,8 @@
|
||||||
all:
|
all:
|
||||||
make slide slideshow
|
make slide
|
||||||
|
|
||||||
slide:
|
slide:
|
||||||
pandoc -t beamer --include-in-header=./style.tex monads.md -f markdown-implicit_figures -V colorlinks=true -V linkcolor=blue -V urlcolor=red -o monads.pdf
|
pandoc monads.md --filter pandoc-plot -f markdown-implicit_figures --pdf-engine=typst --template=template.typ -o monads.pdf
|
||||||
|
|
||||||
slideshow:
|
|
||||||
pandoc -t beamer --include-in-header=./style.tex monads.md -f markdown-implicit_figures -V colorlinks=true -V linkcolor=blue -V urlcolor=red -i -o monads-slideshow.pdf
|
|
||||||
|
|
||||||
view:
|
view:
|
||||||
zathura --mode=presentation monads.pdf &
|
zathura --mode=presentation monads.pdf &
|
||||||
|
|
127
monads/monads.md
127
monads/monads.md
|
@ -1,21 +1,23 @@
|
||||||
---
|
---
|
||||||
title:
|
title:
|
||||||
- Monads
|
- Monads in Haskell
|
||||||
author:
|
author:
|
||||||
- Sanchayan Maity
|
- Sanchayan Maity
|
||||||
theme:
|
aspectratio:
|
||||||
- default
|
- 169
|
||||||
classoption:
|
fontsize:
|
||||||
- aspectratio=169
|
- 14pt
|
||||||
|
papersize:
|
||||||
|
- "presentation-16-9"
|
||||||
---
|
---
|
||||||
|
|
||||||
# Agenda
|
## Agenda
|
||||||
|
|
||||||
- Recap of Functors
|
- Recap of Functors
|
||||||
- Recap of Applicative
|
- Recap of Applicative
|
||||||
- Monads
|
- Monads
|
||||||
|
|
||||||
# Functor[^1][^2]
|
## Functor
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
class Functor f where
|
class Functor f where
|
||||||
|
@ -23,8 +25,6 @@ class Functor f where
|
||||||
(<$) :: a -> f b -> f a
|
(<$) :: a -> f b -> f a
|
||||||
```
|
```
|
||||||
|
|
||||||
Functors Laws
|
|
||||||
|
|
||||||
- Must preserve identity
|
- Must preserve identity
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
|
@ -37,16 +37,13 @@ fmap id = id
|
||||||
fmap (f . g) == fmap f . fmap g
|
fmap (f . g) == fmap f . fmap g
|
||||||
```
|
```
|
||||||
|
|
||||||
[^1]: [Category Design Pattern](https://www.haskellforall.com/2012/08/the-category-design-pattern.html)
|
## Higher order kinds
|
||||||
[^2]: [Functor Design Pattern](https://www.haskellforall.com/2012/09/the-functor-design-pattern.html)
|
|
||||||
|
|
||||||
# Higher order kinds[^3]
|
- For something to be a functor, it has to be a first order kind[^1].
|
||||||
|
|
||||||
- For something to be a functor, it has to be a first order kind.
|
[^1]: [Haskell's Kind System](https://diogocastro.com/blog/2018/10/17/haskells-kind-system-a-primer/)
|
||||||
|
|
||||||
[^3]: [Haskell's Kind System](https://diogocastro.com/blog/2018/10/17/haskells-kind-system-a-primer/)
|
## Applicative
|
||||||
|
|
||||||
# Applicative
|
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
class Functor f => Applicative (f :: TYPE -> TYPE) where
|
class Functor f => Applicative (f :: TYPE -> TYPE) where
|
||||||
|
@ -63,7 +60,7 @@ class Functor f => Applicative (f :: TYPE -> TYPE) where
|
||||||
fmap f x = pure f <*> x
|
fmap f x = pure f <*> x
|
||||||
```
|
```
|
||||||
|
|
||||||
# Examples
|
## Examples
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
pure (+1) <*> [1..3]
|
pure (+1) <*> [1..3]
|
||||||
|
@ -85,7 +82,7 @@ pure (+1) <*> [1..3]
|
||||||
[(1,3),(1,4),(2,3),(2,4)]
|
[(1,3),(1,4),(2,3),(2,4)]
|
||||||
```
|
```
|
||||||
|
|
||||||
# Use cases[^4]
|
## Use cases
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
Person
|
Person
|
||||||
|
@ -94,7 +91,7 @@ Person
|
||||||
<*> parseTelephone "telephone" o
|
<*> parseTelephone "telephone" o
|
||||||
```
|
```
|
||||||
|
|
||||||
Can also be written as
|
Can also be written as[^2]
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
liftA3 Person
|
liftA3 Person
|
||||||
|
@ -102,9 +99,9 @@ liftA3 Person
|
||||||
(parseInt "age" o)
|
(parseInt "age" o)
|
||||||
(parseTelephone "telephone" o)
|
(parseTelephone "telephone" o)
|
||||||
```
|
```
|
||||||
[^4]: [FP Complete - Crash course to Applicative syntax](https://www.fpcomplete.com/haskell/tutorial/applicative-syntax/)
|
[^2]: [FP Complete - Crash course to Applicative syntax](https://www.fpcomplete.com/haskell/tutorial/applicative-syntax/)
|
||||||
|
|
||||||
# Use cases[^5]
|
## Use cases
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
parsePerson :: Parser Person
|
parsePerson :: Parser Person
|
||||||
|
@ -118,9 +115,7 @@ parsePerson = do
|
||||||
pure $ Person name age
|
pure $ Person name age
|
||||||
```
|
```
|
||||||
|
|
||||||
[^5]: [FP Complete - Crash course to Applicative syntax](https://www.fpcomplete.com/haskell/tutorial/applicative-syntax/)
|
## Use cases
|
||||||
|
|
||||||
# Use cases[^6]
|
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
helper :: () -> Text -> () -> () -> Int -> () -> Person
|
helper :: () -> Text -> () -> () -> Int -> () -> Person
|
||||||
|
@ -136,10 +131,7 @@ parsePerson = helper
|
||||||
<*> endOfLine
|
<*> endOfLine
|
||||||
```
|
```
|
||||||
|
|
||||||
[^6]: [FP Complete - Crash course to Applicative syntax](https://www.fpcomplete.com/haskell/tutorial/applicative-syntax/)
|
## Lifting
|
||||||
|
|
||||||
|
|
||||||
# Lifting
|
|
||||||
|
|
||||||
- Seeing Functor as unary lifting and Applicative as n-ary lifting
|
- Seeing Functor as unary lifting and Applicative as n-ary lifting
|
||||||
|
|
||||||
|
@ -153,7 +145,7 @@ liftA4 :: Applicative f => ..
|
||||||
|
|
||||||
Where `liftA0 = pure` and `liftA1 = fmap`.
|
Where `liftA0 = pure` and `liftA1 = fmap`.
|
||||||
|
|
||||||
# Monoidal functors
|
## Monoidal functors
|
||||||
|
|
||||||
- Remember Monoid?
|
- Remember Monoid?
|
||||||
|
|
||||||
|
@ -177,7 +169,7 @@ instance Monoid a => Applicative ((,) a) where
|
||||||
(u, f) <*> (v, x) = (u `mappend` v, f x)
|
(u, f) <*> (v, x) = (u `mappend` v, f x)
|
||||||
```
|
```
|
||||||
|
|
||||||
# Where are monoids again
|
## Where are monoids again
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
fmap (+1) ("blah", 0)
|
fmap (+1) ("blah", 0)
|
||||||
|
@ -193,17 +185,15 @@ liftA2 (,) [1, 2] [3, 4]
|
||||||
[(1,3),(1,4),(2,3),(2,4)]
|
[(1,3),(1,4),(2,3),(2,4)]
|
||||||
```
|
```
|
||||||
|
|
||||||
# Function apply
|
## Function apply
|
||||||
|
|
||||||
- Applying a function to an `effectful` argument
|
- Applying a function to an `effectful` argument
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
(<$>) :: Functor m => (a -> b) -> m a -> m b
|
(<$>) :: Functor m => (a -> b) -> m a -> m b
|
||||||
(<*>) :: Applicative m => m (a -> b) -> m a -> m b
|
|
||||||
(=<<) :: Monad m => (a -> m b) -> m a -> m b
|
|
||||||
```
|
```
|
||||||
|
|
||||||
# Applicative laws
|
## Applicative laws
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
-- Identity
|
-- Identity
|
||||||
|
@ -219,23 +209,26 @@ pure f <*> pure x = pure (f x)
|
||||||
u <*> pure y = pure ($ y) <*> u
|
u <*> pure y = pure ($ y) <*> u
|
||||||
```
|
```
|
||||||
|
|
||||||
# Operators[^7]
|
## Operators
|
||||||
|
|
||||||
- `pure` wraps up a pure value into some kind of Applicative
|
- `pure` wraps up a pure value into some kind of Applicative
|
||||||
- `liftA2` applies a pure function to the values inside two `Applicative` wrapped values
|
- `liftA2` applies a pure function to the values inside two `Applicative` wrapped values
|
||||||
- `<$>` operator version of `fmap`
|
- `<$>` operator version of `fmap`
|
||||||
- `<*>` apply a wrapped function to a wrapped value
|
- `<*>` apply a wrapped function to a wrapped value
|
||||||
- `*>`, `<*`
|
- `*>`, `<*`
|
||||||
|
- See more at[^3]
|
||||||
|
|
||||||
[^7]: [FP Complete - Crash course to Applicative syntax](https://www.fpcomplete.com/haskell/tutorial/applicative-syntax/)
|
[^3]: [FP Complete - Crash course to Applicative syntax](https://www.fpcomplete.com/haskell/tutorial/applicative-syntax/)
|
||||||
|
|
||||||
# Monad, is that you?[^8]
|
## Monad, is that you?
|
||||||
|
|
||||||
![*_Monads_*](burrito-monad.png){width=60%}
|
![*_Monads_*](burrito-monad.png){width=60%}
|
||||||
|
|
||||||
[^8]: [The Unreasonable Effectiveness of Metaphor](https://argumatronic.com/posts/2018-09-02-effective-metaphor.html)
|
- Unreasonable Effectiveness of Metaphor[^4]
|
||||||
|
|
||||||
# Motivation - I
|
[^4]: [The Unreasonable Effectiveness of Metaphor](https://argumatronic.com/posts/2018-09-02-effective-metaphor.html)
|
||||||
|
|
||||||
|
## Motivation - I
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
safeInverse :: Float -> Maybe Float
|
safeInverse :: Float -> Maybe Float
|
||||||
|
@ -251,7 +244,7 @@ sqrtInverse1 :: Float -> Maybe (Maybe Float)
|
||||||
sqrtInverse1 x = safeInverse <$> (safeSqrt x)
|
sqrtInverse1 x = safeInverse <$> (safeSqrt x)
|
||||||
```
|
```
|
||||||
|
|
||||||
# Motivation - I
|
## Motivation - I
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
joinMaybe :: Maybe (Maybe a) -> Maybe a
|
joinMaybe :: Maybe (Maybe a) -> Maybe a
|
||||||
|
@ -265,7 +258,7 @@ sqrtInverse2 x = joinMaybe $ safeInverse <$> (safeSqrt x)
|
||||||
-- join :: Monad m => m (m a) -> m a
|
-- join :: Monad m => m (m a) -> m a
|
||||||
```
|
```
|
||||||
|
|
||||||
# Motivation - II
|
## Motivation - II
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
|
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
|
||||||
|
@ -282,7 +275,7 @@ sqrtInverse x = (>>=) (safeSqrt x) safeInverse
|
||||||
-- (>>=) :: Monad m => m a -> (a -> m b) -> m b
|
-- (>>=) :: Monad m => m a -> (a -> m b) -> m b
|
||||||
```
|
```
|
||||||
|
|
||||||
# Motivation - III
|
## Motivation - III
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
(>=>) :: (a -> Maybe b) -> (b -> Maybe c) -> (a -> Maybe c)
|
(>=>) :: (a -> Maybe b) -> (b -> Maybe c) -> (a -> Maybe c)
|
||||||
|
@ -297,13 +290,13 @@ sqrtInverse3 = safeSqrt >=> safeInverse
|
||||||
-- (>=>) :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)
|
-- (>=>) :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)
|
||||||
```
|
```
|
||||||
|
|
||||||
# Motivations
|
## Motivations
|
||||||
|
|
||||||
- Flattening
|
- Flattening
|
||||||
- Sequencing
|
- Sequencing
|
||||||
- Composition
|
- Composition
|
||||||
|
|
||||||
# Monad
|
## Monad
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
class Applicative m => Monad (m :: Type -> Type) where
|
class Applicative m => Monad (m :: Type -> Type) where
|
||||||
|
@ -315,7 +308,7 @@ import Control.Monad (join)
|
||||||
join :: Monad m => m (m a) -> m a
|
join :: Monad m => m (m a) -> m a
|
||||||
```
|
```
|
||||||
|
|
||||||
# `do` notation
|
## Just **do**
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
|
@ -326,7 +319,7 @@ main = do
|
||||||
putStrLn greeting
|
putStrLn greeting
|
||||||
```
|
```
|
||||||
|
|
||||||
# Monad laws
|
## Monad laws
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
-- Left identity
|
-- Left identity
|
||||||
|
@ -339,11 +332,11 @@ x >>= return == x
|
||||||
m >>= (\x -> k x >>= h) == (m >>= k) >>= h
|
m >>= (\x -> k x >>= h) == (m >>= k) >>= h
|
||||||
```
|
```
|
||||||
|
|
||||||
# ???
|
## ???
|
||||||
|
|
||||||
![*_WTH_*](endofunctor.jpg){width=60%}
|
![*_WTH_*](endofunctor.jpg){width=60%}
|
||||||
|
|
||||||
# Monoids recap
|
## Monoids recap
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
class Semigroup m where
|
class Semigroup m where
|
||||||
|
@ -357,7 +350,7 @@ class Semigroup m => Monoid m where
|
||||||
mappend = (<>)
|
mappend = (<>)
|
||||||
```
|
```
|
||||||
|
|
||||||
# Some Math
|
## Some Math
|
||||||
|
|
||||||
![*_Morphism_*](morphism.png){width=30%}
|
![*_Morphism_*](morphism.png){width=30%}
|
||||||
|
|
||||||
|
@ -365,7 +358,7 @@ class Semigroup m => Monoid m where
|
||||||
- Arrows between objects (morphisms): functions mapping one object to another
|
- Arrows between objects (morphisms): functions mapping one object to another
|
||||||
- Two categories: **Set** and **Hask**
|
- Two categories: **Set** and **Hask**
|
||||||
|
|
||||||
# Categories
|
## Categories
|
||||||
|
|
||||||
- **Set**
|
- **Set**
|
||||||
- Category of sets
|
- Category of sets
|
||||||
|
@ -376,9 +369,9 @@ class Semigroup m => Monoid m where
|
||||||
- Arrows between objects `a` & `b` are functions of type `a -> b`
|
- Arrows between objects `a` & `b` are functions of type `a -> b`
|
||||||
- `a -> b` also a `Type` in **Hask**
|
- `a -> b` also a `Type` in **Hask**
|
||||||
- If `A -> B` and `B -> C`, then `A -> C` ~= `.` in **Hask**
|
- If `A -> B` and `B -> C`, then `A -> C` ~= `.` in **Hask**
|
||||||
- Fun fact: Function composition forms a monoid! (See [Endo](https://hackage.haskell.org/package/base-4.20.0.1/docs/Data-Monoid.html#t:Endo)).
|
- Fun fact: Function composition forms a monoid! (See [Endo](https://hackage.haskell.org/package/base-4.20.0.1/docs/Data-Monoid.html##t:Endo)).
|
||||||
|
|
||||||
# Monads are monoids...
|
## Monads are monoids...
|
||||||
|
|
||||||
In Haskell
|
In Haskell
|
||||||
|
|
||||||
|
@ -400,24 +393,24 @@ Type
|
||||||
a -> m b
|
a -> m b
|
||||||
```
|
```
|
||||||
|
|
||||||
# Now?
|
## Now?
|
||||||
|
|
||||||
![*_WTH_*](endofunctor2.jpg){width=80%}
|
![*_WTH_*](endofunctor2.jpg){width=80%}
|
||||||
|
|
||||||
# Contrasts with Monad
|
## Contrasts with Monad
|
||||||
|
|
||||||
- No data dependency between `f a` and `f b`
|
- No data dependency between `f a` and `f b`
|
||||||
- Result of `f a` can't possibly influence the behaviour of `f b`
|
- Result of `f a` can't possibly influence the behaviour of `f b`
|
||||||
- That needs something like `a -> f b`
|
- That needs something like `a -> f b`
|
||||||
|
|
||||||
# Applicative vs Monads
|
## Applicative vs Monads
|
||||||
|
|
||||||
- Applicative
|
- Applicative
|
||||||
* Effects
|
* Effects
|
||||||
* Batching and aggregation
|
* Batching and aggregation
|
||||||
* Concurrency/Independent
|
* Concurrency/Independent
|
||||||
- Parsing context free grammar
|
- Parsing context free grammar
|
||||||
- Exploring all branches of computation (see [`Alternative`](https://hackage.haskell.org/package/base-4.20.0.1/docs/Control-Applicative.html#t:Alternative))
|
- Exploring all branches of computation (see [`Alternative`](https://hackage.haskell.org/package/base-4.20.0.1/docs/Control-Applicative.html##t:Alternative))
|
||||||
|
|
||||||
- Monads
|
- Monads
|
||||||
* Effects
|
* Effects
|
||||||
|
@ -426,14 +419,14 @@ a -> m b
|
||||||
- Parsing context sensitive grammar
|
- Parsing context sensitive grammar
|
||||||
- Branching on previous results
|
- Branching on previous results
|
||||||
|
|
||||||
# Weaker but better
|
## Weaker but better
|
||||||
|
|
||||||
- Weaker than monads but thus also more common
|
- Weaker than monads but thus also more common
|
||||||
- Lends itself to optimisation (See Facebook's [Haxl](https://hackage.haskell.org/package/haxl) project)
|
- Lends itself to optimisation (See Facebook's [Haxl](https://hackage.haskell.org/package/haxl) project)
|
||||||
- Always opt for the least powerful mechanism to get things done
|
- Always opt for the least powerful mechanism to get things done
|
||||||
- No dependency issues or branching? just use applicative
|
- No dependency issues or branching? just use applicative
|
||||||
|
|
||||||
# State monad
|
## State monad
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
newtype State s a = State { runState :: s -> (a, s) }
|
newtype State s a = State { runState :: s -> (a, s) }
|
||||||
|
@ -452,7 +445,7 @@ instance Applicative (State s) where
|
||||||
(aTob a, s'')
|
(aTob a, s'')
|
||||||
```
|
```
|
||||||
|
|
||||||
# State monad
|
## State monad
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
instance Monad (State s) where
|
instance Monad (State s) where
|
||||||
|
@ -473,7 +466,7 @@ get :: State s s
|
||||||
get = State $ \s -> (s, s)
|
get = State $ \s -> (s, s)
|
||||||
```
|
```
|
||||||
|
|
||||||
# State monad
|
## State monad
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
put :: s -> State s ()
|
put :: s -> State s ()
|
||||||
|
@ -487,7 +480,7 @@ eval (State sa) x = let (a, _) = sa x
|
||||||
in a
|
in a
|
||||||
```
|
```
|
||||||
|
|
||||||
# Context
|
## Context
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
type Stack = [Int]
|
type Stack = [Int]
|
||||||
|
@ -505,7 +498,7 @@ tos :: State Stack Int
|
||||||
tos = State $ \(x:xs) -> (x, x:xs)
|
tos = State $ \(x:xs) -> (x, x:xs)
|
||||||
```
|
```
|
||||||
|
|
||||||
# Context
|
## Context
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
stackManip :: State Stack Int
|
stackManip :: State Stack Int
|
||||||
|
@ -520,7 +513,7 @@ stackManip = do
|
||||||
testState = eval stackManip empty
|
testState = eval stackManip empty
|
||||||
```
|
```
|
||||||
|
|
||||||
# Reader monad
|
## Reader monad
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
class Monad m => MonadReader r m | m -> r where
|
class Monad m => MonadReader r m | m -> r where
|
||||||
|
@ -528,7 +521,7 @@ class Monad m => MonadReader r m | m -> r where
|
||||||
local :: (r -> r) -> m a -> m a
|
local :: (r -> r) -> m a -> m a
|
||||||
```
|
```
|
||||||
|
|
||||||
# Context
|
## Context
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
|
@ -544,7 +537,7 @@ jerry = do
|
||||||
return (env ++ " This is Jerry.")
|
return (env ++ " This is Jerry.")
|
||||||
```
|
```
|
||||||
|
|
||||||
# Context
|
## Context
|
||||||
|
|
||||||
```haskell
|
```haskell
|
||||||
tomAndJerry :: Reader String String
|
tomAndJerry :: Reader String String
|
||||||
|
@ -557,10 +550,8 @@ runJerryRun :: String
|
||||||
runJerryRun = runReader tomAndJerry "Who is this?"
|
runJerryRun = runReader tomAndJerry "Who is this?"
|
||||||
```
|
```
|
||||||
|
|
||||||
# Questions
|
## Questions
|
||||||
|
|
||||||
- Reach out on
|
- Reach out on
|
||||||
* Email: me@sanchayanmaity.net
|
* Email: me@sanchayanmaity.net
|
||||||
* Mastodon: [sanchayanmaity.com](https://sanchayanmaity.com/@sanchayan)
|
* Mastodon: [sanchayanmaity.com](https://sanchayanmaity.com/@sanchayan)
|
||||||
* Telegram: [t.me/SanchayanMaity](https://t.me/SanchayanMaity)
|
|
||||||
* Blog: [sanchayanmaity.net](https://sanchayanmaity.net/)
|
|
||||||
|
|
Binary file not shown.
|
@ -1 +0,0 @@
|
||||||
\logo{\includegraphics[height=0.5cm]{../images/Haskell.jpg}\vspace{220pt}\hspace{8pt}}
|
|
131
monads/template.typ
Normal file
131
monads/template.typ
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
#import "@preview/diatypst:0.2.0": *
|
||||||
|
#show: slides.with(
|
||||||
|
title: "Monads in Haskell",
|
||||||
|
authors: ("Sanchayan Maity"),
|
||||||
|
ratio: 16/9,
|
||||||
|
layout: "large",
|
||||||
|
toc: false,
|
||||||
|
footer: false,
|
||||||
|
count: true,
|
||||||
|
)
|
||||||
|
|
||||||
|
$definitions.typst()$
|
||||||
|
|
||||||
|
#show terms: it => {
|
||||||
|
it.children
|
||||||
|
.map(child => [
|
||||||
|
#strong[#child.term]
|
||||||
|
#block(inset: (left: 1.5em, top: -0.4em))[#child.description]
|
||||||
|
])
|
||||||
|
.join()
|
||||||
|
}
|
||||||
|
|
||||||
|
#set table(
|
||||||
|
inset: 6pt,
|
||||||
|
stroke: none
|
||||||
|
)
|
||||||
|
|
||||||
|
#show figure.where(
|
||||||
|
kind: table
|
||||||
|
): set figure.caption(position: $if(table-caption-position)$$table-caption-position$$else$top$endif$)
|
||||||
|
|
||||||
|
#show figure.where(
|
||||||
|
kind: image
|
||||||
|
): set figure.caption(position: $if(figure-caption-position)$$figure-caption-position$$else$bottom$endif$)
|
||||||
|
|
||||||
|
$if(template)$
|
||||||
|
#import "$template$": conf
|
||||||
|
$else$
|
||||||
|
$template.typst()$
|
||||||
|
$endif$
|
||||||
|
|
||||||
|
$for(header-includes)$
|
||||||
|
$header-includes$
|
||||||
|
|
||||||
|
$endfor$
|
||||||
|
#show: doc => conf(
|
||||||
|
$if(title)$
|
||||||
|
title: [$title$],
|
||||||
|
$endif$
|
||||||
|
$if(subtitle)$
|
||||||
|
subtitle: [$subtitle$],
|
||||||
|
$endif$
|
||||||
|
$if(author)$
|
||||||
|
authors: (
|
||||||
|
$for(author)$
|
||||||
|
$if(author.name)$
|
||||||
|
( name: [$author.name$],
|
||||||
|
affiliation: [$author.affiliation$],
|
||||||
|
email: [$author.email$] ),
|
||||||
|
$else$
|
||||||
|
( name: [$author$],
|
||||||
|
affiliation: "",
|
||||||
|
email: "" ),
|
||||||
|
$endif$
|
||||||
|
$endfor$
|
||||||
|
),
|
||||||
|
$endif$
|
||||||
|
$if(keywords)$
|
||||||
|
keywords: ($for(keywords)$$keyword$$sep$,$endfor$),
|
||||||
|
$endif$
|
||||||
|
$if(date)$
|
||||||
|
date: [$date$],
|
||||||
|
$endif$
|
||||||
|
$if(lang)$
|
||||||
|
lang: "$lang$",
|
||||||
|
$endif$
|
||||||
|
$if(region)$
|
||||||
|
region: "$region$",
|
||||||
|
$endif$
|
||||||
|
$if(abstract)$
|
||||||
|
abstract: [$abstract$],
|
||||||
|
$endif$
|
||||||
|
$if(margin)$
|
||||||
|
margin: ($for(margin/pairs)$$margin.key$: $margin.value$,$endfor$),
|
||||||
|
$endif$
|
||||||
|
$if(papersize)$
|
||||||
|
paper: "$papersize$",
|
||||||
|
$endif$
|
||||||
|
$if(mainfont)$
|
||||||
|
font: ("$mainfont$",),
|
||||||
|
$endif$
|
||||||
|
$if(fontsize)$
|
||||||
|
fontsize: $fontsize$,
|
||||||
|
$endif$
|
||||||
|
$if(section-numbering)$
|
||||||
|
sectionnumbering: "$section-numbering$",
|
||||||
|
$endif$
|
||||||
|
cols: $if(columns)$$columns$$else$1$endif$,
|
||||||
|
doc,
|
||||||
|
)
|
||||||
|
|
||||||
|
$for(include-before)$
|
||||||
|
$include-before$
|
||||||
|
|
||||||
|
$endfor$
|
||||||
|
$if(toc)$
|
||||||
|
#outline(
|
||||||
|
title: auto,
|
||||||
|
depth: $toc-depth$
|
||||||
|
);
|
||||||
|
$endif$
|
||||||
|
|
||||||
|
$body$
|
||||||
|
|
||||||
|
$if(citations)$
|
||||||
|
$if(csl)$
|
||||||
|
|
||||||
|
#set bibliography(style: "$csl$")
|
||||||
|
$elseif(bibliographystyle)$
|
||||||
|
|
||||||
|
#set bibliography(style: "$bibliographystyle$")
|
||||||
|
$endif$
|
||||||
|
$if(bibliography)$
|
||||||
|
|
||||||
|
#bibliography($for(bibliography)$"$bibliography$"$sep$,$endfor$)
|
||||||
|
$endif$
|
||||||
|
$endif$
|
||||||
|
$for(include-after)$
|
||||||
|
|
||||||
|
$include-after$
|
||||||
|
$endfor$
|
Loading…
Reference in a new issue