Author: Antoine Champion
Date: 2022-04-27

# User Guide

#### Antoine Champion

#### 2022-04-27

## Introduction

This package adds an `optional` type, similar to `Option` in F#, OCaml and Scala, to `Maybe` in Haskell, and to nullable types in `C#`.

It should be used instead of `NULL` for values that might be missing or otherwise invalid.

This package also introduces pattern matching.

## Using the optional type

`option` is an object wrapper which indicates whether the object is valid or not.

### Declaring an optional object

An optional variable can be set to `option(object)` or to `none`.

    a <- option(5)
    class(a)

    ## [1] "optional"

Operators and print will have the same behavior with an `optional` than with its base type.

    a == 5

    ## [1] TRUE

    a

    ## [1] 5

Note that `option(option(obj))` equals `option(obj)` and that `option(none)` equals `FALSE`.

To check whether an `optional` object is set to a value or to `none`, one can use the function `some()`.

    a <- option(5)
    some(a)

    ## [1] TRUE

    a <- none
    some(a)

    ## [1] FALSE

### Optionals on functions

Given a function `f()`, to handle properly `optional` arguments and wraps its return type into an `optional`, one should use `make_opt()` the following way:

    f_opt <- make_opt(f)

1. Every `optional` argument passed to `f_opt()` will be converted to its original type before being sent to `f()`. If one or more of them is `none`, several behaviors are available (see `?make_opt`).
2. If `f()` returns null, or if an error is thrown during its execution, then `f_opt()` returns `none`. Else it will return `optional(f(...))`.

For instance:

    c_opt <- make_opt(c)
    c_opt(option(2), none, option(5))

    ## [1] 2 5

    c_opt()

    ## [1] "None"

## Pattern matching

Patterns are used in many functional languages in order to process variables in an exhaustive way.

The syntax is the following:

    match_with( variable,
    pattern , result-function,
    ...

If `variable` matches a `pattern`, `result-function` is called. For comparing optional types, it is a better habit to use `match_with()` rather than a conditional statement.

    library(magrittr)

    ## Warning: le package 'magrittr' a été compilé avec la version R 4.1.3

    a <- 5
    match_with(a,
      . %>% option(.),          paste,
      none,                   function() "Error!"
    )

    ## [1] "5"

1. Each `pattern` can be either:
   - an object or a primitive type (direct comparison with `variable`),
   - a list (match if `variable` is in the list),
   - a `magrittr` functional sequence that matches if it returns `variable`. The dot `.` denotes the variable to be matched.
2. If `result-function` takes no arguments, it will be called as is. Else, the only argument that will be sent is `variable`. You can also use the fallthrough function `fallthrough()` to permit the matching to continue even if the current pattern is matched.

    a <- 4
    match_with(a,
      1,                 function() "Matched exact value",
      list(2, 3, 4),     fallthrough(function() "Matched in list"),
      . %>% if (. > 3)., function(x) paste0("Matched in condition: ",x,">3")
    )

    ## [1] "Matched in list"           "Matched in condition: 4>3"