sourcedemos/monads.xtl

1⍝!/usr/bin/env xetal 2⍝# The Maybe monad from the Maybe library: computations that can fail, 3⍝# chained so that the first failure stops the chain. 4⍝# 5⍝# Run it with ./demos/monads.xtl or "xetal run demos/monads.xtl", or as 6⍝# a notebook with "just show demos/monads.xtl". Each line prints a 7⍝# result, or the default (-1, or 0 for m_aybe) where a division by zero 8⍝# emptied the maybe. Read how b_ind chains steps right to left. 9 10ᵐ⁼u̲se< "Maybe" 11 12⍝## Division that can fail 13 14⍝# a u:d_iv b: a / b in a maybe, or the empty maybe when b is 0, 15⍝# instead of stopping the program. 16ᵘd̲iv ← { a b → b = 0 ? 'ᵐn̲othing◆ ᵐj̲ust a ÷ b } 17 18⍝ o_r takes a maybe's value, or a default (on the left) when it is 19⍝ empty. 20-1 ᵐo̲r 100 ᵘd̲iv 4 21-1 ᵐo̲r 100 ᵘd̲iv 0 22 23⍝## Chains 24 25⍝ b_ind chains steps that can fail, right to left like APL: 100 / 4, 26⍝ then / 5, then / 2. 27⍝# x halved, as a maybe. 28ᵘh̲alf ← { x → x ᵘd̲iv 2 } 29⍝# x divided by 5, as a maybe. 30ᵘf̲ifth ← { x → x ᵘd̲iv 5 } 31-1 ᵐo̲r 'ᵘh̲alf ᵐb̲ind 'ᵘf̲ifth ᵐb̲ind 100 ᵘd̲iv 4 32 33⍝ A zero anywhere in the chain gives the default: nothing after it 34⍝ runs. 35⍝# x divided by 0: always the empty maybe. 36ᵘb̲yZero ← { x → x ᵘd̲iv 0 } 37-1 ᵐo̲r 'ᵘh̲alf ᵐb̲ind 'ᵘb̲yZero ᵐb̲ind 100 ᵘd̲iv 4 38 39⍝## Mapping and both cases 40 41⍝ m_ap applies an ordinary function inside the maybe. 42-1 ᵐo̲r '{ ⍵ × 10 } ᵐm̲ap 9 ᵘd̲iv 3 43 44⍝ m_aybe takes both cases at once: a function and a default. 450 '{ ⍵ + 1 } ᵐm̲aybe 9 ᵘd̲iv 3 460 '{ ⍵ + 1 } ᵐm̲aybe 9 ᵘd̲iv 0