Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions concepts/options/about.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# About

The `Option` type is the F# language mechanism for dealing with values that may or may not exist.
It provides a type-safe alternative to the use of `mull`, which is common in other languages for dealing with such values.
It provides a type-safe alternative to the use of `null`, which is common in other languages for dealing with such values.
It is used in many standard F# library functions, so understanding it is essential for effective use of the standard F# library.

## Benefits of using the `Option` type
Expand All @@ -22,9 +22,14 @@ The `Option` type is a generic type (having an underlying type).
The following function demonstrates how to create an `Option` value:

```fsharp
let keepIfPositive (a: int) : Option<int> = if a > 0 then Some a else None
let keepIfPositive (a: int) : int option = if a > 0 then Some a else None
```

~~~~exercism/note
`T option` is the postfix syntax equivalent for `Option<T>`; the two syntax forms can be used interchangeably.
However, according to the F# Style Guide, the postfix notation is preferred for Option types (see [F# Style Guide section on Formatting Types and Type Annotations][fsharp-style-guide-generic-types-syntax]).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ErikSchierboom, it looks like the link did not render as expected in the UI. Can you please take a look and suggest a fix? Also, any hints on how to preview Exercism-specific markup before merging to main?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes. the exercism blocks can't refer to link referals outside the block. So feel free to inline the link here

~~~~

A typical use case for an `Option` is search functions.
For example, the `List.tryFind` function returns `Some index` when the item is in the list (where `index` is the position of the requested value in the list), or `None` when the item is not in the list.

Expand All @@ -34,7 +39,7 @@ The idiomatic way to read an `Option` value is via pattern matching, as shown in

```fsharp
// Returns "Hello, <name>!" if the name is provided; otherwise returns "Hello, you!"
let sayHello (optionalName: Option<string>): string =
let sayHello (optionalName: string option): string =
match optionalName with
| Some name -> "Hello, " + name + "!"
| None -> "Hello, you!"
Expand All @@ -48,11 +53,12 @@ sayHello None

## Unwrapping Options with default values

`Option`s can be "unwrapped" (converted to their contained type) by providing default values using the `Option.defaultValue` function. This is particularly useful when you want to ensure that the value is not `None`.
`Option`s can be "unwrapped" (converted to their contained type) by providing default values with the `Option.defaultValue` function.
This is particularly useful when you want to ensure that the value is not `None`.
For example:

```fsharp
Option.defaultValue "" Some "F#"
Option.defaultValue "" (Some "F#")
// --> "F#"

Option.defaultValue 0 None
Expand All @@ -63,3 +69,5 @@ Option.defaultValue 0 None

The `Option` module also includes functions that correspond to the functions that are available for lists, arrays, sequences, and other collection types, such as `Option.map`, `Option.iter`, `Option.forall`, `Option.count`.
These functions enable `Option`s to be treated like a collection of zero or one elements.

[fsharp-style-guide-generic-types-syntax]: https://learn.microsoft.com/en-us/dotnet/fsharp/style-guide/formatting#for-types-prefer-prefix-syntax-for-generics-foot-with-some-specific-exceptions
18 changes: 13 additions & 5 deletions concepts/options/introduction.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Introduction

The `Option` type is the F# language mechanism for dealing with values that may or may not exist.
It provides a type-safe alternative to the use of `mull`, which is common in other languages for dealing with such values.
It provides a type-safe alternative to the use of `null`, which is common in other languages for dealing with such values.
It is used in many standard F# library functions, so understanding it is essential for effective use of the standard F# library.

## Usage
Expand All @@ -12,16 +12,21 @@ The `Option` type is a generic type (having an underlying type).
The following function demonstrates how to create an `Option` value:

```fsharp
let keepIfPositive (a: int) : Option<int> = if a > 0 then Some a else None
let keepIfPositive (a: int) : int option = if a > 0 then Some a else None
```

~~~~exercism/note
`T option` is the postfix syntax equivalent for `Option<T>`; the two syntax forms can be used interchangeably.
However, according to the F# Style Guide, the postfix notation is preferred for Option types (see [F# Style Guide section on Formatting Types and Type Annotations][fsharp-style-guide-generic-types-syntax]).
~~~~

## Reading the content of an Option value

The idiomatic way to read an `Option` value is via pattern matching, as shown in the following example:

```fsharp
// Returns "Hello, <name>!" if the name is provided; otherwise returns "Hello, you!"
let sayHello (optionalName: Option<string>): string =
let sayHello (optionalName: string option): string =
match optionalName with
| Some name -> "Hello, " + name + "!"
| None -> "Hello, you!"
Expand All @@ -35,8 +40,9 @@ sayHello None

## Unwrapping Options with default values

`Option`s can be "unwrapped" (converted to their contained type) by providing default values using the `Option.defaultValue` function.
This is particularly useful when you want to ensure that the value is not `None`. For example:
`Option`s can be "unwrapped" (converted to their contained type) by providing default values with the `Option.defaultValue` function.
This is particularly useful when you want to ensure that the value is not `None`.
For example:

```fsharp
Option.defaultValue "" (Some "F#")
Expand All @@ -45,3 +51,5 @@ Option.defaultValue "" (Some "F#")
Option.defaultValue 0 None
// --> 0
```

[fsharp-style-guide-generic-types-syntax]: https://learn.microsoft.com/en-us/dotnet/fsharp/style-guide/formatting#for-types-prefer-prefix-syntax-for-generics-foot-with-some-specific-exceptions
2 changes: 1 addition & 1 deletion exercises/concept/role-playing-game/.docs/hints.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The `revive` function must return either `Some <player>` or `None`, where `<play
Consider using a match expression to cover both the `Some` and `None` cases, as in the following example:

```fsharp
let exists (x: Option<int>) =
let exists (x: int option) =
match x with
| Some n -> true
| None -> false
Expand Down
4 changes: 2 additions & 2 deletions exercises/concept/role-playing-game/.docs/instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ A player's character is represented by the following type:

```fsharp
type Player = {
Name: Option<string>
Name: string option
Level: int
Health: int
Mana: Option<int>
Mana: int option
}
```

Expand Down
18 changes: 13 additions & 5 deletions exercises/concept/role-playing-game/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Introduction

The `Option` type is the F# language mechanism for dealing with values that may or may not exist.
It provides a type-safe alternative to the use of `mull`, which is common in other languages for dealing with such values.
It provides a type-safe alternative to the use of `null`, which is common in other languages for dealing with such values.
It is used in many standard F# library functions, so understanding it is essential for effective use of the standard F# library.

## Usage
Expand All @@ -12,16 +12,21 @@ The `Option` type is a generic type (having an underlying type).
The following function demonstrates how to create an `Option` value:

```fsharp
let keepIfPositive (a: int) : Option<int> = if a > 0 then Some a else None
let keepIfPositive (a: int) : int option = if a > 0 then Some a else None
```

~~~~exercism/note
`T option` is the postfix syntax equivalent for `Option<T>`; the two syntax forms can be used interchangeably.
However, according to the F# Style Guide, the postfix notation is preferred for Option types (see [F# Style Guide section on Formatting Types and Type Annotations][fsharp-style-guide-generic-types-syntax]).
~~~~

## Reading the content of an Option value

The idiomatic way to read an `Option` value is via pattern matching, as shown in the following example:

```fsharp
// Returns "Hello, <name>!" if the name is provided; otherwise returns "Hello, you!"
let sayHello (optionalName: Option<string>): string =
let sayHello (optionalName: string option): string =
match optionalName with
| Some name -> "Hello, " + name + "!"
| None -> "Hello, you!"
Expand All @@ -35,8 +40,9 @@ sayHello None

## Unwrapping Options with default values

`Option`s can be "unwrapped" (converted to their contained type) by providing default values using the `Option.defaultValue` function.
This is particularly useful when you want to ensure that the value is not `None`. For example:
`Option`s can be "unwrapped" (converted to their contained type) by providing default values with the `Option.defaultValue` function.
This is particularly useful when you want to ensure that the value is not `None`.
For example:

```fsharp
Option.defaultValue "" (Some "F#")
Expand All @@ -45,3 +51,5 @@ Option.defaultValue "" (Some "F#")
Option.defaultValue 0 None
// --> 0
```

[fsharp-style-guide-generic-types-syntax]: https://learn.microsoft.com/en-us/dotnet/fsharp/style-guide/formatting#for-types-prefer-prefix-syntax-for-generics-foot-with-some-specific-exceptions
6 changes: 3 additions & 3 deletions exercises/concept/role-playing-game/.meta/Exemplar.fs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
module RolePlayingGame

type Player = {
Name: Option<string>
Name: string option
Level: int
Health: int
Mana: Option<int>
Mana: int option
}

let introduce (player: Player): string =
Option.defaultValue "Mighty Magician" player.Name

let revive (player: Player): Option<Player> =
let revive (player: Player): Player option =
if player.Health > 0 then
None

Expand Down
6 changes: 3 additions & 3 deletions exercises/concept/role-playing-game/RolePlayingGame.fs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
module RolePlayingGame

type Player = {
Name: Option<string>
Name: string option
Level: int
Health: int
Mana: Option<int>
Mana: int option
}

let introduce (player: Player): string =
failwith "Please implement this function"

let revive (player: Player): Option<Player> =
let revive (player: Player): Player option =
failwith "Please implement this function"

let castSpell (manaCost: int) (player: Player): Player * int =
Expand Down