Skip to content

Commit 8b35146

Browse files
committed
Fix indentation
1 parent bcf934e commit 8b35146

File tree

1 file changed

+71
-68
lines changed

1 file changed

+71
-68
lines changed

docsrc/content/tutorial.fsx

+71-68
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)