Skip to content

Commit a7892c0

Browse files
committed
main
1 parent 3e868d6 commit a7892c0

File tree

8 files changed

+265
-76
lines changed

8 files changed

+265
-76
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# Functional Quick Start
2+
3+
## Function as Primitive
4+
5+
## Type Composition
6+
7+
The shape of type and behaviors are isolated.
8+
Functions as first-class citizens, **they don't belong to any type but modules.**
9+
10+
```fsharp
11+
type Point = { X: float; Y: float }
12+
13+
module Point =
14+
let distance p1 p2 =
15+
sqrt ((p2.X - p1.X) ** 2.0 + (p2.Y - p1.Y) ** 2.0)
16+
17+
let translate dx dy point =
18+
{ point with
19+
X = point.X + dx
20+
Y = point.Y + dy }
21+
22+
let p1 = { X = 1.0; Y = 2.0 }
23+
let p2 = Point.translate 3.0 4.0 p1
24+
```
25+
26+
<!-- TODO: add example to show type composition -->
27+
<!-- TODO: add description about function as objective and value as subjective -->
28+
29+
## Hindley-Milner Type System
30+
31+
```fsharp
32+
let add a b = a + b
33+
let foo = add 1 2 // inferred as int -> int -> int
34+
let bar = add 1.0 2,0 // can't infer // [!code error]
35+
```
36+
37+
<!-- TODO: add more appropriate example -->
38+
39+
## Immutable Value
40+
41+
Values are immutable since constructed by default.
42+
43+
```fsharp
44+
let p1 = { X = 1.0; Y = 2.0 }
45+
// there's no even a assignment statement for variable in fsharp
46+
// fsharp use = to check equality
47+
let cond: bool = p1.X = 0 // [!code highlight]
48+
```
49+
50+
> [!NOTE]
51+
> fsharp does have ability to mark variable and field as `mutable` but definitely not recommended unless necessary.
52+
53+
## How to Construct Values
54+
55+
There's two kinds of value construction in functional languages
56+
57+
- Record
58+
- creation on literal(with inference)
59+
- direct access to members
60+
- best for pure data abstraction
61+
- Single-Case Discriminated Union
62+
- requires constructor function on creation
63+
- requires deconstruction on pattern matching to access the members
64+
- best for types that require semantic identification, validation
65+
66+
```fsharp
67+
type Student = { name: string; age: int } // record
68+
type Person = Person of name: string * age: int // case type with constructor
69+
70+
let person: Person = Person("foo", 18)
71+
72+
printfn
73+
"%A"
74+
(match person with // requires deconstruction // [!code highlight]
75+
| Person(name, _) -> name) // [!code highlight]
76+
77+
let student = { name = "foo"; age = 18 } // the target type is inferred here
78+
let _ = student.name // dot accessor for records // [!code highlight]
79+
```
80+
81+
## Discriminated Unions
82+
83+
**Discriminate Unions** uses new type to **wrap** over a known type to provide extra **label/description**.
84+
Such semantic difference is enforced by **nominal type system**. The following example shows how to define a `Shape` union with sub-types,
85+
the subjective relation is **not done by object inheritance** but by simple grouping since we don't need to maintain the statue thanks to **immutability**.
86+
87+
```fsharp
88+
type Shape =
89+
// `of` clause defines constructor
90+
| Circle of float // float is type for the unnamed parameter
91+
| EquilateralTriangle of double
92+
| Square of double
93+
| Rectangle of double * double // two unnamed parameter definition typed as double, separated by *
94+
```
95+
96+
> [!NOTE]
97+
> There's no multiple constructors in fsharp
98+
99+
> [!NOTE]
100+
> Typescript as a structural typing language doesn't have discriminated union but union simply because there's no nominal system.
101+
>```ts
102+
>// NOTE: they're not wrapped as nominal types
103+
>type LogLevel =
104+
> | 'error'
105+
> | 'infor'
106+
> | 'debug'
107+
> | 'trace'
108+
>```
109+
110+
## Pattern Matching
111+
112+
On the basis of **constructor** and **DU** we can have **Pattern Matching**.
113+
114+
## Functor
115+
116+
## Applicative
117+
118+
## Monad
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Cloning
2+
3+
## Conditional Clone
4+
A repository contains commits, and a commit could contain trees(folder objects) and blobs(file objects).
5+
Sometimes you might need to conditionally exclude them on clone to save disk space.
6+
Git has special flags to do such job.
7+
8+
### Filtering Commits
9+
10+
When a repository is especially large at size, and you're only interested in how to build the software from source, then it's a perfect scenario to apply `--depth` option in git.
11+
A depth is a integer representing **the range of commits from new to old**.
12+
When `--depth=1` is specified, it means to **fetch latest snapshot of the remote only**.
13+
14+
The following repository has more than 8GB in total with full commits, while less than 500Mb with `--depth=1` applied.
15+
16+
```sh
17+
git clone [email protected]:NixOS/nixpkgs.git --depth 1
18+
```
19+
20+
If you inspect the log you will find there's only one commit available on local.
21+
22+
```console
23+
[sharpchen@nixos:~/projects/nixpkgs]$ git log --pretty=format:"%H"
24+
6e00a2ec0af992e46494f5700c631101090271ca
25+
```
26+
27+
> [!NOTE]
28+
> Using `--depth` to generate a clone is also called as **shallow clone**
29+
> To recover your repository to a full clone, use `git fetch --unshallow`
30+
31+
### Filtering Blobs
32+
33+
Blobs are file abstraction in git, when `--filter=blob:none` is specified on clone, git will not fetch files **besides `HEAD`** on this clone.
34+
Git will defer the fetch when you access any other blobs from commits that are not downloaded on local.
35+
That is, `--filter=blob:none` is a lazy initialization of the repository.
36+
37+
```sh
38+
git clone [email protected]:NixOS/nixpkgs.git --filter=blob:none
39+
```
40+
41+
> [!NOTE]
42+
> `git fetch` on a blobless repository will only fetch new commits from remote, it doesn't recover it to full repository.
43+
44+
### Filtering Trees
45+
46+
`--filter=tree:0` is similar to `--filter=blob:none` but **even slimmer**.
47+
The whole structure including tree and blob are lazily initialized.
48+
49+
```sh
50+
git clone [email protected]:NixOS/nixpkgs.git --filter=tree:0
51+
```
52+
53+
### Conclusion
54+
55+
If you want a slime clone:
56+
- if you don't care commit history, use `--depth=1`(which is the **slimmest** approach)
57+
- if you care only commits history, use `--filter=tree:0`
58+
- TODO: explain why do I need `blob:none` when `tree:0` is available?
59+
60+
## Clone with Submodule
61+
62+
Fetching submodule on clone:
63+
64+
```sh
65+
git clone <url> --recursive
66+
```
67+
68+
If you forgot to append `--recursive` option when cloning for the first time, you can still remedy using the following command.
69+
70+
```sh
71+
git submodule update --init --recursive
72+
```

docs/document/Skill/Git/docs/Submodule.md

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,3 @@ git submodule add <repository_url> <path_to_submodule>
1010
```
1111

1212
Details of submodules can be inspected from `.gitmodules`
13-
14-
## Clone with Submodule
15-
16-
Fetching submodule on clone:
17-
18-
```sh
19-
git clone <url> --recursive
20-
```
21-
22-
If you forgot to append `--recursive` option when cloning for the first time, you can still remedy using the following command.
23-
24-
```sh
25-
git submodule update --init --recursive
26-
```

docs/document/Skill/Lua/docs/Function.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ end
4444
```lua
4545
local function foo(...) return unpack { ... } end
4646
_ = { foo(1, 2, 3) } -- [1, 2, 3]
47+
_ = unpack({ 1, 2, 3, 4 }, 2) -- slice from index 2 to end(as splattered)
48+
_ = { unpack({ 1, 2, 3, 4 }, 2) } -- slice from index 2 to end(collected as table)
4749
```
4850

4951
## Iterator Function
Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
11
# Glossary
22

3-
- **modem**(调制/解调器): short hand of **modulator-demodulator**
3+
4+
| original | translation | description |
5+
| --------------- | --------------- | --------------- |
6+
| packet | 数据包 | |
7+
| packet switch | 数据包交换 | |
8+
| modem | 调制/解调器 | shorthand of **modulator-demodulator** |
9+
| optical modem | 光猫 | |
10+
| communication links | 通讯线路 | |
11+
| ISP | 互联网服务供应商⸺|Internet Service Providers |
12+
| Transmission Control Protocol || TCP |
13+
| Internet Protocol || IP |
14+

docs/document/Skill/Nix/docs/1.Language/String.md

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ Nix does not handle string evaluation for all types but string, path and a nix p
1212
For other types, requires `builtins.toString`.
1313

1414
```nix
15-
"${123}" # cannot evaluate number to string # [!code error]
16-
"${builtins.toString 123}" # ok # [!code highlight]
15+
"${123}" # cannot evaluate number to string # [!code error]
16+
"${builtins.toString 123}" # ok # [!code highlight]
1717
```
1818

1919
### Evaluation for Package
@@ -63,7 +63,7 @@ stdenv.mkDerivation {
6363
}
6464
```
6565

66-
Some editors support syntax injection for multi-line string.
66+
`nvim-treesitter` plugin supports syntax injection for multi-line string.
6767
Add filetype as comment before the string to inform syntax parser.
6868

6969
```nix
@@ -80,14 +80,21 @@ in {}
8080

8181
### Escaping
8282

83+
Escaping in double-quote string is pretty standard, using `\`
84+
85+
```nix
86+
"[[ ! \${FOO-} ]] || return"
87+
```
88+
89+
8390
To escape in multi-line, prefix with `''`
8491

8592
```nix
8693
''
87-
This is a new line ''\n # [!code highlight]
94+
This is a new line ''\n # [!code highlight]
8895
This is a single quote: ''\'
89-
This is also a single quote: '''
90-
This is not a interpolation ''${foo} # [!code highlight]
96+
This is two single quotes: '''
97+
This is not a interpolation ''${foo} # [!code highlight]
9198
''
9299
```
93100

@@ -97,3 +104,8 @@ To escape in multi-line, prefix with `''`
97104
"foo" + "bar"
98105
```
99106

107+
To concat an list, use `builtins.concatStringsSep`
108+
109+
```nix
110+
builtins.concatStringsSep "\n" [ "line1" "line2" "line3" ]
111+
```

0 commit comments

Comments
 (0)