Skip to content

Commit 10b8989

Browse files
committed
Merge branch 'master' into v1.6
2 parents 5d9f199 + 9cb4063 commit 10b8989

24 files changed

Lines changed: 751 additions & 335 deletions

.config/dotnet-tools.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
]
1010
},
1111
"fsdocs-tool": {
12-
"version": "16.1.1",
12+
"version": "19.1.1",
1313
"commands": [
1414
"fsdocs"
1515
]

.github/workflows/dotnetcore.yml

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ env:
1212

1313
on:
1414
push:
15-
branches: [ master, v1.2, v1.3, v1.4, v1.5 ]
15+
branches: [ master, v1.2, v1.3, v1.4, v1.5, v1.6 ]
1616
pull_request:
17-
branches: [ master, v1.2, v1.3, v1.4, v1.5 ]
17+
branches: [ master, v1.2, v1.3, v1.4, v1.5, v1.6 ]
1818
jobs:
1919
build:
2020

@@ -23,13 +23,19 @@ jobs:
2323
steps:
2424
- uses: actions/checkout@v2
2525
- name: Setup .NET Core
26-
uses: actions/setup-dotnet@v1
26+
uses: actions/setup-dotnet@v3
2727
with:
28-
dotnet-version: 6.0.201
28+
dotnet-version: |
29+
8.0.x
30+
7.0.x
2931
- name: Restore
3032
run: git submodule update --init --recursive
3133
- name: Build with dotnet
3234
run: dotnet build build.proj --configuration Release
35+
- name: Set Timezone
36+
uses: szenius/set-timezone@v1.2
37+
with:
38+
timezoneWindows: "Nepal Standard Time"
3339
- name: Test with dotnet
3440
run: dotnet test build.proj -v n
3541

@@ -39,12 +45,14 @@ jobs:
3945
steps:
4046
- uses: actions/checkout@v2
4147
- name: Setup .NET Core
42-
uses: actions/setup-dotnet@v1
48+
uses: actions/setup-dotnet@v3
4349
with:
44-
dotnet-version: 6.0.201
50+
dotnet-version: |
51+
8.0.x
52+
7.0.x
53+
6.0.x
4554
- name: Restore
4655
run: git submodule update --init --recursive
47-
4856
- name: Extract branch name
4957
shell: bash
5058
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
@@ -78,14 +86,14 @@ jobs:
7886
runs-on: windows-latest
7987
steps:
8088
- uses: actions/checkout@v2
81-
- name: Setup .NET Core 6
82-
uses: actions/setup-dotnet@v1
83-
with:
84-
dotnet-version: 6.0.201
85-
- name: Setup .NET Core 5
86-
uses: actions/setup-dotnet@v1
89+
- name: Setup .NET Core
90+
uses: actions/setup-dotnet@v3
8791
with:
88-
dotnet-version: 5.0.405
92+
dotnet-version: |
93+
8.0.x
94+
7.0.x
95+
6.0.x
96+
5.0.x
8997
- name: Restore
9098
run: git submodule update --init --recursive
9199
- name: Build All Docs

.github/workflows/fable.yml

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ name: Fable
22

33
on:
44
push:
5-
branches: [ master, v1.2, v1.3, v1.4, v1.5 ]
5+
branches: [ master, v1.2, v1.3, v1.4, v1.5, v1.6 ]
66
pull_request:
7-
branches: [ master, v1.2, v1.3, v1.4, v1.5 ]
7+
branches: [ master, v1.2, v1.3, v1.4, v1.5, v1.6 ]
88

99

1010
jobs:
@@ -18,11 +18,12 @@ jobs:
1818
- name: Remove global json
1919
run: rm global.json
2020
- name: Setup .NET Core
21-
uses: actions/setup-dotnet@v1
21+
uses: actions/setup-dotnet@v3
2222
with:
23-
dotnet-version: 6.0.201
24-
- name: Restore
25-
run: git submodule update --init --recursive
23+
dotnet-version: |
24+
8.0.x
25+
7.0.x
26+
6.0.x
2627
- name: Restore tools
2728
run: dotnet tool restore
2829
- name: Install fable
@@ -47,14 +48,13 @@ jobs:
4748
run: git submodule update --init --recursive
4849
- name: Remove global json
4950
run: rm global.json
50-
- name: Setup .NET Core 7
51-
uses: actions/setup-dotnet@v1
52-
with:
53-
dotnet-version: 7.0.200
54-
- name: Setup .NET Core 6
55-
uses: actions/setup-dotnet@v1
51+
- name: Setup .NET Core
52+
uses: actions/setup-dotnet@v3
5653
with:
57-
dotnet-version: 6.0.201
54+
dotnet-version: |
55+
8.0.x
56+
7.0.x
57+
6.0.x
5858
- name: Restore tools
5959
run: dotnet tool restore
6060
- name: Install jq
@@ -84,9 +84,12 @@ jobs:
8484
- name: Remove global json
8585
run: rm global.json
8686
- name: Setup .NET Core
87-
uses: actions/setup-dotnet@v1
87+
uses: actions/setup-dotnet@v3
8888
with:
89-
dotnet-version: 6.0.201
89+
dotnet-version: |
90+
8.0.x
91+
7.0.x
92+
6.0.x
9093
- name: Restore tools
9194
run: dotnet tool restore
9295
# - name: Run tests (Fable2 subset but on .net)

DEVELOPER_GUIDE.md

Lines changed: 27 additions & 31 deletions
Large diffs are not rendered by default.

appveyor.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ before_build:
1111
init:
1212
- git config --global core.autocrlf input
1313
install:
14-
- cmd: choco install dotnetcore-sdk -y
14+
- ps: Invoke-WebRequest 'https://dot.net/v1/dotnet-install.ps1' -OutFile 'dotnet-install.ps1'
15+
- ps: ./dotnet-install.ps1 -Version 8.0.100 -InstallDir "C:\Program Files\dotnet"
16+
#- cmd: winget install Microsoft.DotNet.SDK.8
1517
- cmd: git submodule update --init --recursive
1618
build_script:
1719
- cmd: dotnet restore ./FSharpPlus.sln

docsrc/content/tutorial.fsx

Lines changed: 71 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
// it to define helpers that you do not want to show in the documentation.
44

55
#r @"../../src/FSharpPlus/bin/Release/netstandard2.0/FSharpPlus.dll"
6-
#nowarn "0058" // We need to cheat a bit with indentation here.
76

87
(**
98
Introducing FSharpPlus
@@ -20,12 +19,11 @@ Introducing FSharpPlus
2019
#r @"nuget: FSharpPlus"
2120
```
2221
*)
23-
open FSharpPlus
24-
25-
(**
26-
Ignore warnings about F# metadata if any.
2722

23+
(*** hide ***)
24+
module [<AutoOpen>] E1 =
2825

26+
(**
2927
Now we'll start with a quick overview of the features presented in F#+.
3028
3129
### Generic functions
@@ -36,33 +34,35 @@ here's an example with <code>map</code> ([fmap](https://wiki.haskell.org/Functor
3634
3735
*)
3836

39-
map string [|2;3;4;5|]
40-
// val it : string [] = [|"2"; "3"; "4"; "5"|]
37+
open FSharpPlus
4138

42-
map ((+) 9) (Some 3)
43-
// val it : int option = Some 12
39+
map string [|2;3;4;5|]
40+
// val it : string [] = [|"2"; "3"; "4"; "5"|]
4441

45-
open FSharpPlus.Data
42+
map ((+) 9) (Some 3)
43+
// val it : int option = Some 12
4644

47-
map string (NonEmptyList.create 2 [3;4;5])
48-
// val it : NonEmptyList<string> = {Head = "2"; Tail = ["3"; "4"; "5"];}
45+
open FSharpPlus.Data
46+
47+
map string (NonEmptyList.create 2 [3;4;5])
48+
// val it : NonEmptyList<string> = {Head = "2"; Tail = ["3"; "4"; "5"];}
4949

5050
(**
5151
They're also available for your own types as long as they contain the appropriated method with the expected signature
5252
*)
5353

5454

55-
type Tree<'t> =
56-
| Tree of 't * Tree<'t> * Tree<'t>
57-
| Leaf of 't
58-
static member Map (x:Tree<'a>, f) =
59-
let rec loop f = function
60-
| Leaf x -> Leaf (f x)
61-
| Tree (x, t1, t2) -> Tree (f x, loop f t1, loop f t2)
62-
loop f x
63-
64-
map ((*) 10) (Tree(6, Tree(2, Leaf 1, Leaf 3), Leaf 9))
65-
// val it : Tree<int> = Tree (60,Tree (20,Leaf 10,Leaf 30),Leaf 90)
55+
type Tree<'t> =
56+
| Tree of 't * Tree<'t> * Tree<'t>
57+
| Leaf of 't
58+
static member Map (x:Tree<'a>, f) =
59+
let rec loop f = function
60+
| Leaf x -> Leaf (f x)
61+
| Tree (x, t1, t2) -> Tree (f x, loop f t1, loop f t2)
62+
loop f x
63+
64+
map ((*) 10) (Tree(6, Tree(2, Leaf 1, Leaf 3), Leaf 9))
65+
// val it : Tree<int> = Tree (60,Tree (20,Leaf 10,Leaf 30),Leaf 90)
6666

6767
(**
6868
Generic functions may be seen as an exotic thing in F# that only saves a few key strokes (<code>map</code> instead of <code>List.map</code> or <code>Array.map</code>) still they allow you to reach a higher abstraction level, using ad-hoc polymorphism.
@@ -72,67 +72,70 @@ But more interesting is the use of operators. You can't prefix them with the mod
7272
Here you have a ready-to-use generic bind operator: ``>>=``
7373
*)
7474

75-
let x = ["hello";" ";"world"] >>= (fun x -> Seq.toList x)
76-
// val x : char list = ['h'; 'e'; 'l'; 'l'; 'o'; ' '; 'w'; 'o'; 'r'; 'l'; 'd']
75+
let x = ["hello";" ";"world"] >>= (fun x -> Seq.toList x)
76+
// val x : char list = ['h'; 'e'; 'l'; 'l'; 'o'; ' '; 'w'; 'o'; 'r'; 'l'; 'd']
7777

7878

79-
let tryParseInt : string -> int option = tryParse
80-
let tryDivide x n = if n = 0 then None else Some (x / n)
79+
let tryParseInt : string -> int option = tryParse
80+
let tryDivide x n = if n = 0 then None else Some (x / n)
8181

82-
let y = Some "20" >>= tryParseInt >>= tryDivide 100
83-
// val y : int option = Some 5
82+
let y = Some "20" >>= tryParseInt >>= tryDivide 100
83+
// val y : int option = Some 5
8484

8585
(**
8686
You have also the Kleisli composition (fish) operator: ``>=>``
8787
8888
Which is becoming popular in F# after the [Railway Oriented Programming](https://www.google.ch/#q=railway+oriented+programming) tutorial series
8989
*)
9090

91-
let parseAndDivide100By = tryParseInt >=> tryDivide 100
91+
let parseAndDivide100By = tryParseInt >=> tryDivide 100
9292

93-
let parsedAndDivide100By20 = parseAndDivide100By "20" // Some 5
94-
let parsedAndDivide100By0' = parseAndDivide100By "zero" // None
95-
let parsedAndDivide100By0 = parseAndDivide100By "0" // None
93+
let parsedAndDivide100By20 = parseAndDivide100By "20" // Some 5
94+
let parsedAndDivide100By0' = parseAndDivide100By "zero" // None
95+
let parsedAndDivide100By0 = parseAndDivide100By "0" // None
9696

97-
let parseElement n = List.tryItem n >=> tryParseInt
98-
let parsedElement = parseElement 2 ["0"; "1";"2"]
97+
let parseElement n = List.tryItem n >=> tryParseInt
98+
let parsedElement = parseElement 2 ["0"; "1";"2"]
9999

100100
(**
101101
But don't forget the above used operators are generic, so we can change the type of our functions and we get a different functionality for free:
102102
*)
103103

104104
(*** hide ***)
105-
module E2 =
105+
open FSharpPlus
106+
107+
(*** hide ***)
108+
module E2 =
106109

107-
let tryParseInt x : Choice<int, string> =
108-
match tryParse x with
109-
| Some x -> Choice1Of2 x
110-
| None -> Choice2Of2 ("Failed to parse " + x)
110+
let tryParseInt x : Choice<int, string> =
111+
match tryParse x with
112+
| Some x -> Choice1Of2 x
113+
| None -> Choice2Of2 ("Failed to parse " + x)
111114

112115

113-
let tryDivide x n =
114-
if n = 0 then Choice2Of2 "Can't divide by zero"
115-
else Choice1Of2 (x / n)
116+
let tryDivide x n =
117+
if n = 0 then Choice2Of2 "Can't divide by zero"
118+
else Choice1Of2 (x / n)
116119

117120
(**
118121
The test code remains unchanged, but we get a more interesting functionality
119122
*)
120123

121-
let parseAndDivide100By = tryParseInt >=> tryDivide 100
124+
let parseAndDivide100By = tryParseInt >=> tryDivide 100
122125

123-
let parsedAndDivide100By20 = parseAndDivide100By "20" // Choice1Of2 5
124-
let parsedAndDivide100By0' = parseAndDivide100By "zero" // Choice2Of2 "Failed to parse zero"
125-
let parsedAndDivide100By0 = parseAndDivide100By "0" // Choice2Of2 "Can't divide by zero"
126+
let parsedAndDivide100By20 = parseAndDivide100By "20" // Choice1Of2 5
127+
let parsedAndDivide100By0' = parseAndDivide100By "zero" // Choice2Of2 "Failed to parse zero"
128+
let parsedAndDivide100By0 = parseAndDivide100By "0" // Choice2Of2 "Can't divide by zero"
126129

127130

128131
(**
129132
130133
Also when working with combinators, the generic applicative functor (space invaders) operator is very handy: ``<*>``
131134
*)
132135

133-
let sumAllOptions = Some (+) <*> Some 2 <*> Some 10 // val sumAllOptions : int option = Some 12
136+
let sumAllOptions = Some (+) <*> Some 2 <*> Some 10 // val sumAllOptions : int option = Some 12
134137

135-
let sumAllElemets = [(+)] <*> [10; 100] <*> [1; 2; 3] // int list = [11; 12; 13; 101; 102; 103]
138+
let sumAllElemets = [(+)] <*> [10; 100] <*> [1; 2; 3] // int list = [11; 12; 13; 101; 102; 103]
136139

137140
(**
138141
@@ -154,43 +157,43 @@ from https://github.com/ekmett/lens/wiki/Examples
154157
First, open F#+ Lens
155158
*)
156159

157-
open FSharpPlus.Lens
160+
open FSharpPlus.Lens
158161

159162
(** Now, you can read from lenses (``_2`` is a lens for the second component of a tuple) *)
160163

161-
let r1 = ("hello","world")^._2
162-
// val it : string = "world"
164+
let r1 = ("hello","world")^._2
165+
// val it : string = "world"
163166

164167
(** and you can write to lenses. *)
165-
let r2 = setl _2 42 ("hello","world")
166-
// val it : string * int = ("hello", 42)
168+
let r2 = setl _2 42 ("hello","world")
169+
// val it : string * int = ("hello", 42)
167170

168171
(** Composing lenses for reading (or writing) goes in the order an imperative programmer would expect, and just uses ``(<<)``. *)
169-
let r3 = ("hello",("world","!!!"))^.(_2 << _1)
170-
// val it : string = "world"
172+
let r3 = ("hello",("world","!!!"))^.(_2 << _1)
173+
// val it : string = "world"
171174

172-
let r4 = setl (_2 << _1) 42 ("hello",("world","!!!"))
173-
// val it : string * (int * string) = ("hello", (42, "!!!"))
175+
let r4 = setl (_2 << _1) 42 ("hello",("world","!!!"))
176+
// val it : string * (int * string) = ("hello", (42, "!!!"))
174177

175178
(** You can make a Getter out of a pure function with ``to'``. *)
176-
let r5 = "hello"^.to' length
177-
// val it : int = 5
179+
let r5 = "hello"^.to' length
180+
// val it : int = 5
178181

179182
(** You can easily compose a Getter with a Lens just using ``(<<)``. No explicit coercion is necessary. *)
180-
let r6 = ("hello",("world","!!!"))^. (_2 << _2 << to' length)
181-
// val it : int = 3
183+
let r6 = ("hello",("world","!!!"))^. (_2 << _2 << to' length)
184+
// val it : int = 3
182185

183186
(** As we saw above, you can write to lenses and these writes can change the type of the container. ``(.->)`` is an infix alias for ``set``. *)
184-
let r7 = _1 .-> "hello" <| ((),"world")
185-
// val it : string * string = ("hello", "world")
187+
let r7 = _1 .-> "hello" <| ((),"world")
188+
// val it : string * string = ("hello", "world")
186189

187190
(** It can be used in conjunction with ``(|>)`` for familiar von Neumann style assignment syntax: *)
188-
let r8 = ((), "world") |> _1 .-> "hello"
189-
// val it : string * string = ("hello", "world")
191+
let r8 = ((), "world") |> _1 .-> "hello"
192+
// val it : string * string = ("hello", "world")
190193

191194
(** Conversely view, can be used as an prefix alias for ``(^.)``. *)
192-
let r9 = view _2 (10,20)
193-
// val it : int = 20
195+
let r9 = view _2 (10,20)
196+
// val it : int = 20
194197

195198
(**
196199

0 commit comments

Comments
 (0)