user
Demonstrate in your programming language the following:

1. Construct a Maybe Monad by writing the 'bind' function and the 'unit' (sometimes known as 'return') function for that Monad (or just use what the language already has implemented)
2. Make two functions, each which take a number and return a monadic number, e.g. Int -> Maybe Int and Int -> Maybe String
3. Compose the two functions with bind

A Monad is a single type which encapsulates several other types, eliminating boilerplate code. In practice it acts like a dynamically typed computational sequence, though in many cases the type issues can be resolved at compile time.

A Maybe Monad is a monad which specifically encapsulates the type of an undefined value.
assistant
(formerly Perl 6)

**Works with**: Rakudo version 2019.11

It is exceptionally difficult to come up with a compelling valuable use for
a Maybe monad in Raku. Monads are most useful in languages that don't have
exceptions and/or only allow a single point of entry/exit from a subroutine.

There are very good reasons to have those restrictions. It makes it much less
complex to reason about a programs correctness and actually *prove* that a
program is correct, but those restrictions also lead to oddities like Monads,
just as a way to work around those restrictions.

The task description asks for two functions that take an Int and return a Maybe
Int or Maybe Str, but those distinctions are nearly meaningless in Raku. See
below.

```
my $monad = <42>;
say 'Is $monad an Int?: ', $monad ~~ Int;
say 'Is $monad a  Str?: ', $monad ~~ Str;
say 'Wait, what? What exactly is $monad?: ', $monad.^name;

```

Output:

```
Is $monad an Int?: True
Is $monad a  Str?: True
Wait, what? What exactly is $monad?: IntStr
```

$monad is both an Int **and** a Str. It exists in a sort-of quantum state
where what-it-is depends on how-it-is-used. Bolting on some 'Monad' type to do
this will only *remove* functionality that Raku already has.

Ok, say you have a situation where you absolutely do not want an incalculable
value to halt processing. (In a web process perhaps.) In that case, it *might*
be useful to subvert the normal exception handler and just return a "Nothing"
type. Any routine that needs to be able to handle a Nothing type will need to be
informed of it, but for the most part, that just means adding a multi-dispatch
candidate.

```
# Build a Nothing type. When treated as a string it returns the string 'Nothing'.
# When treated as a Numeric, returns the value 'Nil'.
class NOTHING {
    method Str { 'Nothing' }
    method Numeric { Nil }
}

# A generic instance of a Nothing type.
my \Nothing = NOTHING.new;

# A reimplementation of the square-root function. Could just use the CORE one
# but this more fully shows how multi-dispatch candidates are added.

# Handle positive numbers & 0
multi root (Numeric $n where * >= 0) { $n.sqrt }
# Handle Negative numbers (Complex number handling is built in.)
multi root (Numeric $n where * <  0) { $n.Complex.sqrt }
# Else return Nothing
multi root ($n) { Nothing }

# Handle numbers > 0
multi ln (Real $n where * > 0) { log $n, e }
# Else return Nothing
multi ln ($n) { Nothing }

# Handle fraction where the denominator != 0
multi recip (Numeric $n where * != 0) { 1/$n }
# Else return Nothing
multi recip ($n) { Nothing }

# Helper formatting routine
sub center ($s) {
    my $pad = 21 - $s.Str.chars;
    ' ' x ($pad / 2).floor ~ $s ~ ' ' x ($pad / 2).ceiling;
}

# Display the "number" the reciprocal, the root, natural log and the 3 functions
# composed together.
put ('"Number"', 'Reciprocal', 'Square root', 'Natural log', 'Composed')».&center;

# Note how it handles the last two "values". The string 'WAT' is not numeric at
# all; but Ethiopic number 30, times vulgar fraction 1/7, is.
put ($_, .&recip, .&root, .&ln, .&(&ln o &root o &recip) )».&center
  for -2, -1, -0.5, 0, exp(-1), 1, 2, exp(1), 3, 4, 5, 'WAT', ፴ × ⅐;

```

Output:

```
      "Number"             Reciprocal            Square root           Natural log            Composed       
         -2                   -0.5          0+1.4142135623730951i        Nothing               Nothing       
         -1                    -1                   0+1i                 Nothing               Nothing       
        -0.5                   -2           0+0.7071067811865476i        Nothing               Nothing       
          0                  Nothing                  0                  Nothing               Nothing       
 0.36787944117144233    2.718281828459045    0.6065306597126334            -1                    0.5         
          1                     1                     1                     0                     0          
          2                    0.5           1.4142135623730951    0.6931471805599453    -0.3465735902799726 
  2.718281828459045    0.36787944117144233   1.6487212707001282             1                   -0.5         
          3                 0.333333         1.7320508075688772    1.0986122886681098    -0.5493061443340549 
          4                   0.25                    2            1.3862943611198906    -0.6931471805599453 
          5                    0.2            2.23606797749979     1.6094379124341003    -0.8047189562170503 
         WAT                 Nothing               Nothing               Nothing               Nothing       
      4.285714              0.233333         2.0701966780270626     1.455287232606842    -0.727643616303421
```