77 lines
3.2 KiB
Markdown
77 lines
3.2 KiB
Markdown
<p align = "center">
|
||
<img src="https://raw.githubusercontent.com/devicons/devicon/master/icons/haskell/haskell-original.svg" alt="Haskell" width="200"/>
|
||
</p>
|
||
|
||
# Introduction
|
||
After miserably failing my Functional Programming exam and some soul searching, I realized that I never really learned Haskell nor did I ever really understand functional programming. So, I decided to learn Haskell properly. This repository will document my journey in learning Haskell.
|
||
|
||
With the help of some friends!
|
||
|
||
This is going to be structured in a different way than my other repositories. I will have a `sessions` folder where I will document my thought process and the things I learned while during my "lessons". Maybe do Haskell notebooks? I don't know yet.
|
||
|
||
This is the larger, more general README, which will house the main takeaways/revelations of the sessions.
|
||
|
||
## ToC
|
||
- [Introduction](#introduction)
|
||
- [ToC](#toc)
|
||
- [Books and resources](#books-and-resources)
|
||
- [13th of March - Introduction](#13th-of-march---introduction)
|
||
- [\[16th of March - Deriving types\]](#16th-of-march---deriving-types)
|
||
|
||
# Books and resources
|
||
- [Haskell Programming from first principles](http://haskellbook.com/)
|
||
- [Learn you a Haskell for great good](http://learnyouahaskell.com/)
|
||
|
||
|
||
## [13th of March - Introduction](sessions/13_03/notes.md)
|
||
|
||
Big question:
|
||
|
||
> Why is the singly-linked list the most common data structure in functional programming?
|
||
|
||
Because it is the simplest recursive data structure. It is a recursive data structure because it is defined in terms of itself. It is a singly-linked list because it has a head and a tail. The head is the first element of the list and the tail is the rest of the list.
|
||
|
||
<p align="center">
|
||
<img src="assets/list.png" alt="lists" width="700"/>
|
||
</p>
|
||
|
||
> But why not a tree?
|
||
|
||
The tree is simply too complex. Linked lists are easy.
|
||
|
||
## [16th of March - Deriving types]
|
||
|
||
> How does one do this systematically?
|
||
**Eyeball method:**
|
||
Looking at the function definition:
|
||
|
||
1. Each parameter - what is the type of each parameter?
|
||
2. Return type - what is the type of the return value?
|
||
3. If the function calls another function, look at the type of that function.
|
||
4. Replace concrete types with type variables (a, b, c, etc.)
|
||
|
||
**Formal method[^2]:**
|
||
(on paper)
|
||
|
||
1. Write down the type of each argument and subexpression.
|
||
2. Generate equations for how types relate to each other and apply transitivity (if needed).
|
||
e.g.
|
||
$$
|
||
\begin{align*}
|
||
f &:: a \to b \to c \\
|
||
g &:: c \to e \\
|
||
|
||
\implies f \circ g &:: a \to b \to e
|
||
\end{align*}
|
||
$$
|
||
3. Solve the equations for the most general type.
|
||
|
||
|
||
|
||
> Lazy and singly-linked lists, what's the relation?
|
||
A lazy list doesn’t compute all elements at once; it only computes elements as you need them.
|
||
A singly-linked list is naturally great for lazy, because each element points to the next, with the next being a thunk (actual fucking term, meaning a computation that hasn't been evaluated yet[^1]).
|
||
|
||
|
||
[^1]: More generally, a thunk is a subroutine used to inject computation into another subroutine. They delay computation until it is needed. It canonically originates from the verb *think* lmao.
|
||
[^2]: [Hindley–Milner type inference](https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system) |