<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="243229" data-post-id="243229">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="gregvaughn" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/gregvaughn/120/954_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  gregvaughn
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>At risk of going off on a tangent, let me point out that the type system of Erlang (and BEAM) pre-date Scala/F#/Haskell. It was developed in industry, not academia. The creators did not set out to create a functional language, but it happened to meet their requirements best, so that’s what we got.</p>
<p>I’m impressed with the levels of static typing people have been able to achieve, but at a fundamental level there will be mismatches with BEAM-level types because the language designers made different design tradeoffs originally.</p>
<p>This doesn’t help with your specific question(s), but perhaps it will help to moderate your expectations of what is possible/practical and when to expect compromises.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="243229" data-batch-url="/posts/batch_likers">
                        5
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/option-type-compatible-with-comprehensions-in-elixr/46077/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-243229" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="243229"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="243278" data-post-id="243278">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="dimitarvp" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/120/38664_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  dimitarvp
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I completely share the sentiment.</p>
<p>In my experience we can still achieve quite a lot with tagged tuples by the way, especially if they are multiple-level e.g. <code>{:payment_result, {:ok, %{amount: "3.45", currency: "EUR"}}}</code> or <code>{:payment_result, {:error, :payment_gateway_timeout}}</code> etc.</p>
<p>One weird thing I noticed all over my Elixir tenure in companies is how teams avoid nested tuples almost religiously and I have no clue why (especially having in mind that some very prominent library modules like <code>Ecto.Multi</code> make heavy use of them!). Nested tuples helped me in personal projects and when helping various acquaintances bootstrap businesses (by writing some code for them). Haven’t seen downsides so far.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="243278" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/option-type-compatible-with-comprehensions-in-elixr/46077/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-243278" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="243278"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="243280" data-post-id="243280">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="dimitarvp" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/120/38664_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  dimitarvp
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Can’t talk about Scala or Haskell or OCaml (which I still want to learn!) but e.g. in Rust you have this method:</p>
<aside class="onebox allowlistedgeneric" data-onebox-src="https://doc.rust-lang.org/std/option/enum.Option.html#method.iter">
  <header class="source">
      <img src="https://doc.rust-lang.org/static.files/favicon-044be391.svg" class="site-icon" alt="" width="100" height="100">

      <a href="https://doc.rust-lang.org/std/option/enum.Option.html#method.iter" target="_blank" rel="noopener nofollow ugc">doc.rust-lang.org</a>
  </header>

  <article class="onebox-body">
    

<h3><a href="https://doc.rust-lang.org/std/option/enum.Option.html#method.iter" target="_blank" rel="noopener nofollow ugc">pub fn iter(&amp;self) -&gt; Iter&lt;'_, T&gt; ⓘ - Option in std::option - Rust</a></h3>

  <p>Returns an iterator over the possibly contained value. | The `Option` type. See the module level documentation for more.</p>


  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>

<p>…that transforms a <code>Some(value)</code> / <code>None</code> variable into a thing you can iterate on (<code>Enumerable</code> in Elixir lingo).</p>
<p>That would also fit the spirit of “be explicit” in the FP world nicely – don’t convert stuff to something they are not usually supposed to be unless you really need it in your case. So you’d end up with:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Option do
  def to_enumerable({:option, {:some, value}}), do: [value]
  def to_enumerable({:option, :none}), do: [])
end
</code></pre>
<p>Which Rust kind of does as well under the hood – you get an iterable collection with one or zero elements.</p>
<p>Of course you can go all in and just implement the <code>Access</code> protocol, too.</p>
<p>But I don’t think you could get away with emulating things <em>a la</em> Scala style in Elixir without some macro magic or some quite heavy libraries like <code>ok</code> or <code>witchcraft</code>. I personally would prefer having explicit wrappers and using them at the right places for code readability points (and my future self hating me less – but I am aware that your interest in this is mostly academical and not industry-oriented so the point of making future maintenance easier likely doesn’t apply to you at all).</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="243280" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/option-type-compatible-with-comprehensions-in-elixr/46077/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-243280" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="243280"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #13"></div>
  </section>
</div>
    <div class="postbit" id="243295" data-post-id="243295">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="dmitriid" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dmitriid/120/13182_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  dmitriid
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<blockquote>
<p>I am trying to up my Functional Programming (FP) skills and one of the things that newcomers first learn in FP is the Option Type (aka, Maybe Monad).</p>
</blockquote>
<p>Depends on where you learn FP. I learned FP through Lisp, Erlang, and Javascript, and didn’t encounter Option/Maybe until 15 years after I was already happily using most of what FP has to offer.</p>
<p>As with any concepts, do not try to force some programming language paradigms into another programming language: they are usually a bad fit. People have been trying to bolt Haskell/Haskell-like on top of Erlang and then Elixir for literally decades. Nothing works, nothing sticks, and for a good reason.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="243295" data-batch-url="/posts/batch_likers">
                        4
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/option-type-compatible-with-comprehensions-in-elixr/46077/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-243295" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="243295"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #14"></div>
  </section>
</div>
    <div class="postbit" id="243334" data-post-id="243334">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Fl4m3Ph03n1x" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Fl4m3Ph03n1x/120/11709_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Fl4m3Ph03n1x
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="dimitarvp" data-post="14" data-topic="46077">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/48/38664_2.png" class="avatar"> dimitarvp:</div>
<blockquote>
<p>Which Rust kind of does as well under the hood – you get an iterable collection with one or zero elements.</p>
<p>Of course you can go all in and just implement the <code>Access</code> protocol, too.</p>
</blockquote>
</aside>
<p>I learned Ocaml, Scala and only missed Haskell.<br>
Concepts like these were always useful to me. I didn’t know about Rust <code>Option</code> type, but truth is I am right now exploring a similar solution.</p>
<blockquote>
<p>Of course you can go all in and just implement the Access protocol, too.</p>
</blockquote>
<p>I believe you mean the <a href="https://hexdocs.pm/elixir/1.13/Enumerable.html#reduce/3" rel="noopener nofollow ugc">Enumerable</a> protocol, since comprehensions work with Enumerables <img src="https://forum.elixirforum.com/images/emoji/apple/smiley.png?v=15" title=":smiley:" class="emoji" alt=":smiley:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="243334" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/option-type-compatible-with-comprehensions-in-elixr/46077/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-243334" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="243334"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #15"></div>
  </section>
</div>
    <div class="postbit" id="243371" data-post-id="243371">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="al2o3cr" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/al2o3cr/120/3457_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  al2o3cr
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>A random thought: the simplest possible <code>option(t)</code> would be <code>t | nil</code>, for all <code>t</code> besides booleans.</p>
<p><code>map</code> is then spelled <code>&amp;&amp;</code>:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">some_optional &amp;&amp; do_thing_with_value(some_optional)
</code></pre>
<p><code>orElse</code>/<code>withDefault</code> is spelled <code>||</code>:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">some_optional || "default value"
</code></pre>
<p>Alas, <code>do</code>-notation-style chaining doesn’t compile:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir"># DOES NOT COMPILE - variables are not in scope

(valid_name = validate_name(name))
&amp;&amp; (valid_end = validate_end(an_end))
&amp;&amp; (valid_start = validate_start(a_start, an_end))
&amp;&amp; %Event{name: valid_name, start: valid_start, end: valid_end}
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="243371" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/option-type-compatible-with-comprehensions-in-elixr/46077/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-243371" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="243371"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #16"></div>
  </section>
</div>
    <div class="postbit" id="243372" data-post-id="243372">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Fl4m3Ph03n1x" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Fl4m3Ph03n1x/120/11709_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Fl4m3Ph03n1x
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>An interesting thought that merits its own discussion in my opinion.<br>
For now however, I just really want to make something that works with Elixir’s native comprehensions, hence, the Option type which can be built using a list of 1 value internally.</p>
<p>(I am still working on it, believe it or not … )</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="243372" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/option-type-compatible-with-comprehensions-in-elixr/46077/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-243372" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="243372"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #17"></div>
  </section>
</div>
    <div class="postbit" id="243648" data-post-id="243648">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Fl4m3Ph03n1x" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Fl4m3Ph03n1x/120/11709_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Fl4m3Ph03n1x
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<h2><a name="p-243648-answer-1" class="anchor" href="#p-243648-answer-1" aria-label="Heading link" rel="nofollow"></a>Answer</h2>
<p>After searching for all the functional libraries Elixir has on hex, at the time of this writing none matched my main requirement:</p>
<ul>
<li>Being usable with Elixir comprehensions.</li>
</ul>
<p>Some say Elixir comprehensions are not powerful enough for such cases. This is a falsifiable claim, so I  decided to go ahead and try to falsify it.</p>
<h2><a name="p-243648-say-hi-to-optionex-2" class="anchor" href="#p-243648-say-hi-to-optionex-2" aria-label="Heading link" rel="nofollow"></a>Say Hi to <code>Option.ex</code></h2>
<p>Yes, the name is not inspiring. Originality has never been my <em>forté</em>.<br>
But what is this?</p>
<p>Simply put, this is an option type for elixir, aka, Option/Maybe monad. Yes, another one.</p>
<p>And just like what most people coming from languages like Scala/Haskell/Python have come to know, it has a couple of subtypes <code>Some</code> and <code>None</code>.</p>
<p><strong>option.ex</strong></p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Option do
  @type t(elem) :: __MODULE__.Some.t(elem) | __MODULE__.None.t()

  defmodule Some do
    @type t(elem) :: %__MODULE__{val: elem}

    defstruct [:val]

    defimpl Collectable do
      @impl Collectable
      def into(option), do: {option, fn acc, _command -&gt; {:done, acc} end}
    end

    defimpl Enumerable do
      @impl Enumerable
      def count(_some), do: {:ok, 1}

      @impl Enumerable
      def member?(some, element), do: {:ok, some.val == element}

      @impl Enumerable
      def reduce(some, acc, fun)

      def reduce(_some, {:halt, acc}, _fun), do: {:halted, acc}
      def reduce(some, {:suspend, acc}, fun), do: {:suspended, acc, &amp;reduce(some, &amp;1, fun)}
      def reduce([], {:cont, acc}, _fun), do: {:done, acc}

      def reduce(%Option.Some{} = some, {:cont, acc}, fun),
        do: reduce([], fun.(some.val, acc), fun)

      @impl Enumerable
      def slice(_option), do: {:error, __MODULE__}
    end
  end

  defmodule None do
    @type t :: %__MODULE__{}

    defstruct []

    defimpl Collectable do
      @impl Collectable
      def into(option) do
        {option,
         fn
           _acc, {:cont, val} -&gt;
             %Option.Some{val: val}

           acc, :done -&gt;
             acc

           _acc, :halt -&gt;
             :ok
         end}
      end
    end

    defimpl Enumerable do
      @impl Enumerable
      def count(_none), do: {:error, __MODULE__}

      @impl Enumerable
      def member?(_none, _element), do: {:error, __MODULE__}

      @impl Enumerable
      def reduce(none, acc, fun)

      def reduce(_none, {:cont, acc}, _fun), do: {:done, acc}
      def reduce(_none, {:halt, acc}, _fun), do: {:halted, acc}
      def reduce(none, {:suspend, acc}, fun), do: {:suspended, acc, &amp;reduce(none, &amp;1, fun)}

      @impl Enumerable
      def slice(_option), do: {:error, __MODULE__}
    end
  end

  @spec new(any) :: __MODULE__.Some.t(any)
  def new(val), do: %__MODULE__.Some{val: val}

  @spec new :: __MODULE__.None.t()
  def new, do: %__MODULE__.None{}
end
</code></pre>
<p>This works with Elixir comprehensions, and it makes use of the fact that the Optional type is a Functor. This means its main requirement is being able to be mapped over. By converting an abstract container into specific implementation detail (like lists in Elixir) I was able to make it work.</p>
<h2><a name="p-243648-how-can-i-use-it-3" class="anchor" href="#p-243648-how-can-i-use-it-3" aria-label="Heading link" rel="nofollow"></a>How can I use it?</h2>
<p>The main purpose of this was to add an Option type to elixir to use with comprehensions. So a comparison to other languages is useful:</p>
<p><strong>In Scala:</strong></p>
<pre data-code-wrap="scala"><code class="lang-scala">def parseShow(rawShow: String): Option[TvShow] = {
  for {
    name &lt;- extractName(rawShow)
    yearStart &lt;- extractYearStart(rawShow)
    yearEnd &lt;- extractYearEnd(rawShow)
  } yield TvShow(name, yearEnd, yearStart)
}
</code></pre>
<p><strong>In Elixir:</strong></p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  @spec parse_show(String.t()) :: Option.t(TvShow.t())
  def parse_show(raw_show) do
    for name &lt;- extract_name(raw_show),
        year_start &lt;- extract_year_start(raw_show),
        year_end &lt;- extract_year_end(raw_show),
        into: Option.new() do
      %TvShow{name: name, year_end: year_end, year_start: year_start}
    end
  end
</code></pre>
<p>You will see, these two pieces of code are basically identical, with the exception of the line <code>into: Option.new()</code>, which is implicit in the Scala example. Elixir requires it to be explicit, which I personally prefer as well.</p>
<p>I could go on with examples from other languages, but they would all read basically the same. This is because comprehensions are basically the same in most FP languages.</p>
<p>But this doesn’t answer the full original post …</p>
<h2><a name="p-243648-what-about-an-elixir-equivalent-in-tagged-tuples-4" class="anchor" href="#p-243648-what-about-an-elixir-equivalent-in-tagged-tuples-4" aria-label="Heading link" rel="nofollow"></a>What about an Elixir equivalent in tagged tuples?</h2>
<p>You can’t use tagged tuples to achieve the same thing using comprehensions. This is impossible.<br>
However, if we discard comprehensions and focus on Elixir’s other constructs, we can come a little bit closer.</p>
<p>Quoting another prominent member of our community, <a class="mention" href="/u/overminddl1" rel="nofollow">@OvermindDL1</a> :</p>
<blockquote>
<p>Is it possible to simulate the <code>Option</code> type using tagged tuples inside Elixir comprehensions?</p>
<p>Yes, or with <code>with</code> if you want an else, but you’ll want to make the tagged typed be <code>ok: value</code> and <code>error: reason</code> (which is closer to a result type, but it’s a limitation of elixir tuple lists in that they are always tuples). Traditionally <code>{:ok, value}</code> and <code>:error</code> is the “option” type in Elixir, where <code>{:ok, value}</code> and <code>{:error, reason}</code> is the “result” type in Elixir.</p>
</blockquote>
<p>So, if you are coming from a different setting, from a functional language into Elixir, this post and my <code>option.ex</code> is most certainly going to help you.</p>
<p>If however, you’d rather stay away from Mathematical Categories and other functional concepts like you want to stay away from the plague, <code>with</code> statements with other elixir’s constructs ought to serve you well enough.</p>
<p>One is not better than the other, they have different costs/benefits. It’s up to you.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="243648" data-batch-url="/posts/batch_likers">
                        4
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/option-type-compatible-with-comprehensions-in-elixr/46077/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-243648" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="243648"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-solved cat-solved" title="Marked as solution"></div>
  </section>
</div>
    <div class="postbit" id="243650" data-post-id="243650">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="stefanluptak" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/stefanluptak/120/34398_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  stefanluptak
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hey <a class="mention" href="/u/fl4m3ph03n1x" rel="nofollow">@Fl4m3Ph03n1x</a> I am curious about your <code>Option.ex</code> module.<br>
Could you please show us some real-world scenario to better understand the usage? For example, would it be possible for your <code>parse_show</code> function to somehow return the information that <code>year_end</code> is missing in the <code>raw_show</code> or in wrong format?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="243650" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/option-type-compatible-with-comprehensions-in-elixr/46077/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-243650" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="243650"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #19"></div>
  </section>
</div>
    <div class="postbit" id="243654" data-post-id="243654">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Fl4m3Ph03n1x" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Fl4m3Ph03n1x/120/11709_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Fl4m3Ph03n1x
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="stefanluptak" data-post="20" data-topic="46077">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/stefanluptak/48/34398_2.png" class="avatar"> stefanluptak:</div>
<blockquote>
<p>Hey <a class="mention" href="/u/fl4m3ph03n1x" rel="nofollow">@Fl4m3Ph03n1x</a> I am curious about your <code>Option.ex</code> module.<br>
Could you please show us some real-world scenario to better understand the usage?</p>
</blockquote>
</aside>
<p>Let’s assume I have an app that receives data in String format. This data can come from a DB, an API, anyplace.<br>
Our job is to parse this data into a format our application can understand, <code>TvShows</code>:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule TvShow do
  @enforce_keys [:name, :year_start, :year_end]
  defstruct [:name, :year_start, :year_end]

  @type t :: %__MODULE__{
          name: integer(),
          year_start: integer(),
          year_end: integer()
        }
end
</code></pre>
<p>Now, how we we parse this?<br>
We need to parse the name, start year and end year. Here is an example of how a <code>parse_show</code> could look like:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule SafeFunctionsThatReturnOptions do
  alias TvShow
  alias Option
  alias StringHelpers

  @spec parse_show(String.t()) :: Option.t(TvShow.t())
  def parse_show(raw_show) do
    for name &lt;- extract_name(raw_show),
        year_start &lt;- extract_year_start(raw_show),
        year_end &lt;- extract_year_end(raw_show),
        into: Option.new() do
      %TvShow{name: name, year_end: year_end, year_start: year_start}
    end
  end

  @spec extract_name(String.t()) :: Option.t(String.t())
  def extract_name(raw_show) do
    bracket_open_index = StringHelpers.index_of(raw_show, "(")

    if valid_index?(bracket_open_index) do
      raw_show
      |&gt; String.slice(0..(bracket_open_index - 1))
      |&gt; String.trim()
      |&gt; Option.new()
    else
      Option.new()
    end
  end

  @spec extract_year_start(String.t()) :: Option.t(non_neg_integer)
  def extract_year_start(raw_show) do
    bracket_open = StringHelpers.index_of(raw_show, "(")
    dash = StringHelpers.index_of(raw_show, "-")

    for year_str &lt;- parse_year_start(bracket_open, dash, raw_show),
        year &lt;- StringHelpers.to_int_maybe(year_str),
        into: Option.new() do
      year
    end
  end

  @spec extract_year_end(String.t()) :: Option.t(non_neg_integer)
  def extract_year_end(raw_show) do
    dash = StringHelpers.index_of(raw_show, "-")
    bracket_close = StringHelpers.index_of(raw_show, ")")

    for year_str &lt;- parse_year_end(dash, bracket_close, raw_show),
        year &lt;- StringHelpers.to_int_maybe(year_str),
        into: Option.new() do
      year
    end
  end

  @spec parse_year_start(integer, integer, String.t()) :: Option.t(String.t())
  defp parse_year_start(bracket_open_index, dash_index, raw_show) do
    if valid_index?(bracket_open_index) and dash_index &gt;= bracket_open_index + 1 do
      raw_show
      |&gt; String.slice((bracket_open_index + 1)..(dash_index - 1))
      |&gt; Option.new()
    else
      Option.new()
    end
  end

  @spec parse_year_end(integer, integer, String.t()) :: Option.t(String.t())
  defp parse_year_end(dash_index, bracket_end_index, raw_show) do
    if valid_index?(bracket_end_index) and dash_index &lt;= bracket_end_index - 1 do
      raw_show
      |&gt; String.slice((dash_index + 1)..(bracket_end_index - 1))
      |&gt; Option.new()
    else
      Option.new()
    end
  end

  @spec valid_index?(integer) :: boolean
  defp valid_index?(index), do: index != -1
end
</code></pre>
<p>I also took the liberty of adding some helper modules:</p>
<p><strong>StringHelpers</strong>:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule StringHelpers do
  alias ListHelpers

  @spec index_of(String.t(), String.t()) :: integer
  def index_of(str, elem),
    do:
      str
      |&gt; String.codepoints()
      |&gt; ListHelpers.index_of(elem)

  @spec to_int_maybe(String.t()) :: Option.t(integer)
  def to_int_maybe(val) do
    case Integer.parse(val) do
      {num, ""} -&gt; Option.new(num)
      _error -&gt; Option.new()
    end
  end
end
</code></pre>
<p>And <strong>ListHelpers</strong>:</p>
<pre data-code-wrap="eixir"><code class="lang-eixir">defmodule ListHelpers do
  @spec index_of([any], any) :: integer
  def index_of(list, elem), do: search(list, elem, 0)

  @spec search([any], any, integer) :: integer
  defp search([], _elem, _index), do: -1

  defp search([head | tail], elem, index) do
    if head == elem do
      index
    else
      search(tail, elem, index + 1)
    end
  end
end
</code></pre>
<p>I prepared these small examples to look like APIs from other functional languages. My <code>StringHelpers</code> is basically an adaption of something you could find in Java (imperative language mostly) and Scala.</p>
<p>This is how you would use it:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">SafeFunctionsThatReturnOptions.parse_show("")
-&gt; None

SafeFunctionsThatReturnOptions.parse_show("Game of Thrones (2000-2018)")
-&gt; %TvShow{ ... }
</code></pre>
<aside class="quote no-group" data-username="stefanluptak" data-post="20" data-topic="46077">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/stefanluptak/48/34398_2.png" class="avatar"> stefanluptak:</div>
<blockquote>
<p>would it be possible for your <code>parse_show</code> function to somehow return the information that <code>year_end</code> is missing in the <code>raw_show</code> or in wrong format?</p>
</blockquote>
</aside>
<p>No. This is not what the Option type is for. What you are describing is the Result/Error Monad, which is another construct from functional programming. You can however, take the principles applied to create the <code>option.ex</code> and use it to create a <code>result.ex</code> if you want.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="243654" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/option-type-compatible-with-comprehensions-in-elixr/46077/21">Post #20</a>
	                </div>
	            </div>
              <div id="likers-container-243654" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="243654"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #20"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/46077/load_more?page=3">Load more posts (4 remaining)</a>
</div></template></turbo-stream>