---
title: "The Maybe monad"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{the-maybe-monad}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

```{r setup}
library(chronicler)
```

```{r parsermd-chunk-1}
library(chronicler)
library(maybe)
```

`{chronicler}` uses the `{maybe}` package under the hood; `{maybe}` implements the *Maybe* 
monad which provides an elegant solution to situations where functions fail. As an example,
let’s consider the `sqrt()` function decorated using `maybe()`:


```{r parsermd-chunk-2}
m_sqrt <- maybe(sqrt)

m_sqrt(16)
```

`m_sqrt(16)` succeeds and returns `Just 4`. But what happens if it fails?


```{r parsermd-chunk-3}
m_sqrt("10")
```

`m_sqrt("10")` returns `Nothing` because `sqrt("10")` would return an error. Using `maybe()` allows
you to build safe functions that never fail; you can explicitely handle `Nothing` values instead
of having the program crash and stop.

When a computation fails, functions decorated using `record()` also return `Nothing`:


```{r parsermd-chunk-4}
r_sqrt <- record(sqrt)

r_sqrt("16")
```

and when computations succeed, `Just` values are also returned:


```{r parsermd-chunk-5}
r_sqrt <- record(sqrt)

r_sqrt(16)
```

If `Nothing` is passed to a function decorated by `record()`, `Nothing` gets immediately returned.

Users of `{chronicle}` do not need to be familiar with the `{maybe}` package to use it, as conversion
to and from `maybe` objects is handled automatically.

To recuperate the value from a `chronicler` object, users can use `unveil()`:


```{r parsermd-chunk-6}
unveil(r_sqrt(16), "value")
```

`unveil()` converts the value from the `maybe` type to the underlying type of the object. Compare
to:


```{r parsermd-chunk-7}
(r_sqrt(16))$value
```

which returns the `Just` object. To learn more about `{maybe}`, read the 
[package’s](https://armcn.github.io/maybe/) readme which provides a nice introduction.

