Last active
March 18, 2018 01:23
-
-
Save expede/a8047d3f139985682f9a42ce3ed0013b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Interactive Elixir (1.6.4) - press Ctrl+C to exit (type h() ENTER for help) | |
iex(1)> use Witchcraft | |
iex(2)> alias Algae.Maybe | |
# With a Just | |
iex(5)> monad %Maybe.Just{} do | |
...(5)> a <- Maybe.Just.new(1) | |
...(5)> b <- Maybe.Just.new(2) | |
...(5)> return(a + b) | |
...(5)> end | |
%Algae.Maybe.Just{just: 3} | |
# Same with Nothing | |
iex(6)> monad %Maybe.Nothing{} do | |
...(6)> a <- Maybe.Just.new(1) | |
...(6)> b <- Maybe.Just.new(2) | |
...(6)> return(a + b) | |
...(6)> end | |
%Algae.Maybe.Just{just: 3} | |
# Makes no difference if there's something in the Just | |
iex(5)> monad %Maybe.Just{just: 42} do | |
...(5)> a <- Maybe.Just.new(1) | |
...(5)> b <- Maybe.Just.new(2) | |
...(5)> return(a + b) | |
...(5)> end | |
%Algae.Maybe.Just{just: 3} | |
# Because of how Nothing short circuits, we skip the return function | |
iex(7)> monad 12.3456 do # floats are not monads | |
...(7)> a <- Maybe.Just.new(1) | |
...(7)> b <- Maybe.Nothing.new() | |
...(7)> return(a + b) | |
...(7)> end | |
%Algae.Maybe.Nothing{} | |
# `Monad.return/1` is just `Applicative.of/1`, ie: partially applied `of/2` with whatever we hand to the `monad` macro. | |
# There is no type environment carried around in Elixir, so `Monad %Sample{} do` is a way of emulating type metadata for the `return` | |
# | |
# Strictly speaking, all this gets you the ability to: | |
# 1. Write pure-yet-imperative-feeling code, because `return` is familiar | |
# 2. Use `return` in several places without needing to always specify the context that you're in | |
# The example above but using more `return`: | |
iex(8)> monad %Maybe.Nothing{} do | |
...(8)> a <- return(1) | |
...(8)> b <- return(2) | |
...(8)> return(a + b) | |
...(8)> end | |
%Algae.Maybe.Just{just: 3} | |
# This code is far more general (and thus portable) than the one with explicit values on each line. | |
#For example: | |
iex(10)> context_add = | |
...(10)> fn(sample) -> | |
...(10)> monad sample do | |
...(10)> a <- return(1) | |
...(10)> b <- return(2) | |
...(10)> return(a + b) | |
...(10)> end | |
...(10)> end | |
#Function<6.99386804/1 in :erl_eval.expr/5> | |
iex(11)> context_add.([]) | |
[3] | |
iex(12)> context_add.(["these", "values", "are", "thrown out"]) | |
[3] | |
iex(13)> context_add.(%Algae.Either.Right{}) | |
%Algae.Either.Right{right: 3} | |
iex(14)> context_add.(%Algae.Maybe.Nothing{}) | |
%Algae.Maybe.Just{just: 3} | |
iex(15)> context_add.(%Algae.Tree.Rose{}) | |
%Algae.Tree.Rose{forest: [], rose: 3} | |
# Obviously that's a somewhat silly example, but it should help illustrate the behaviour :) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment