patternMinor
Simple/Naive Implementation of Identity and Maybe Monad in Elixir
Viewed 0 times
identitysimplenaiveelixirmaybeandimplementationmonad
Problem
This is my first crack at a identity monad and a maybe monad in Elixir:
I'd like to see if there is a way to make the monad into a protocol since the return and bind seem to be common to all monads.
defmodule Monad do
@doc "v is value to be wrapped as monadic value"
def return(v), do: fn -> v end
@doc "m is monad function, mv is monadic value"
def bind(m, mv), do: m.(mv.())
end
#Simple identity monad
id = fn s -> s end
h = Monad.return(:ok)
r = Monad.bind(id, h)
#Maybe monad
maybe = fn s -> if is_nil(s), do: :error, else: s end
r = Monad.bind(maybe, h)I'd like to see if there is a way to make the monad into a protocol since the return and bind seem to be common to all monads.
Solution
I think you're sort of missing the point with this code - the difference between different kinds of monads (Maybe vs. List vs. Identity, etc.) is in the different implementations of
While for example
The difference between the two being that in one case you only get information that there is no result (
return and bind. I think a good starting place might be reading through a library that implements monads in elixir, like monad. Looking into that you can see that for example Maybe is implemented like this (simplifying):def return(x), do: {:just, x}
def bind({:just, x}, f), do: f.(x)
def bind(:nothing, _), do: :nothing
def fail(_), do: :nothingWhile for example
Error (the second-simplest I think) is implemented like this:def return(x), do: {:ok, x}
def bind(e = {:error, _}, _), do: e
def bind({:ok, x}, f), do: f.(x)
def fail(msg), do: {:error, msg}The difference between the two being that in one case you only get information that there is no result (
:nothing) while in the other you either get a result or some information on the error (represented by {:error, _}). Also note that both have additional helper functions to for example extract the result (presumably at the end of the computation).Code Snippets
def return(x), do: {:just, x}
def bind({:just, x}, f), do: f.(x)
def bind(:nothing, _), do: :nothing
def fail(_), do: :nothingdef return(x), do: {:ok, x}
def bind(e = {:error, _}, _), do: e
def bind({:ok, x}, f), do: f.(x)
def fail(msg), do: {:error, msg}Context
StackExchange Code Review Q#97631, answer score: 3
Revisions (0)
No revisions yet.