<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ivan Lorenz</title>
    <description>The latest articles on DEV Community by Ivan Lorenz (@ivanlorenz).</description>
    <link>https://dev.to/ivanlorenz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F663498%2Faeb30f75-658f-4d51-b911-628a8cce5042.png</url>
      <title>DEV Community: Ivan Lorenz</title>
      <link>https://dev.to/ivanlorenz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ivanlorenz"/>
    <language>en</language>
    <item>
      <title>¿Es Validated un Applicative?</title>
      <dc:creator>Ivan Lorenz</dc:creator>
      <pubDate>Fri, 19 Nov 2021 08:41:09 +0000</pubDate>
      <link>https://dev.to/adevintaspain/es-validated-un-applicative-40bk</link>
      <guid>https://dev.to/adevintaspain/es-validated-un-applicative-40bk</guid>
      <description>&lt;p&gt;Preguntas y respuestas sobre las &lt;a href="https://dev.to/rogervinas/series/14723"&gt;sesiones&lt;/a&gt; &lt;em&gt;live coding&lt;/em&gt; de &lt;a href="https://arrow-kt.io/"&gt;Arrow&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;La siguiente pregunta fue realizada durante la &lt;a href="https://dev.to/adevintaspain/kotlinarrow-gestion-de-errores-con-validated-pcm"&gt;tercera sesión&lt;/a&gt;. Os dejamos también el enlace directo a la &lt;a href="https://github.com/AdevintaSpain/wonderful-freshair-app/discussions/7"&gt;discusión en Github&lt;/a&gt; y el enlace del &lt;a href="https://www.youtube.com/watch?v=989t4x2gMJQ&amp;amp;t=5532s"&gt;vídeo en el momento de la pregunta&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pregunta
&lt;/h2&gt;

&lt;p&gt;Hoy nos toca una pregunta cerrada: ¿es Validated un Applicative?. Intentaremos desarrollar un poco la respuesta.&lt;/p&gt;

&lt;h2&gt;
  
  
  Respuesta
&lt;/h2&gt;

&lt;p&gt;Durante la sesión no respondimos por varias razones: la primera es que intentamos guiar estas sesiones explicando el porqué y cómo introducir &lt;a href="https://arrow-kt.io/"&gt;Arrow&lt;/a&gt; en nuestro código &lt;a href="https://kotlinlang.org/"&gt;Kotlin&lt;/a&gt; en el back-end. Hemos preferido centrarnos en las características que nos ofrecen tipos cómo &lt;em&gt;Either&lt;/em&gt;, &lt;em&gt;Validated&lt;/em&gt; o &lt;em&gt;NonEmptyList&lt;/em&gt; en nuestro trabajo diario con código &lt;a href="https://es.wikipedia.org/wiki/Programaci%C3%B3n_orientada_a_objetos"&gt;OOP&lt;/a&gt; y cómo incorporarlos a nuestro código base, que en la teoría matemática formal que los sustenta, la &lt;a href="https://es.wikipedia.org/wiki/Teor%C3%ADa_de_categor%C3%ADas"&gt;Teoría de categorías&lt;/a&gt;. La segunda es que durante las primeras dos sesiones, no queríamos hablar de &lt;a href="https://es.wikipedia.org/wiki/Programaci%C3%B3n_funcional"&gt;FP&lt;/a&gt;. Nos lo reservamos para las siguientes sesiones.&lt;/p&gt;

&lt;p&gt;De hecho, estas sesiones pretender simular un caso de uso sintético de migración iterativa, más o menos exportable a nuestro día a día, desde &lt;em&gt;OOP&lt;/em&gt; a &lt;em&gt;FP&lt;/em&gt; usando &lt;strong&gt;Kotlin&lt;/strong&gt; y &lt;strong&gt;Arrow&lt;/strong&gt;. Lo hacemos, no porqué creamos que un paradigma de programación sea mejor que el otro en términos absolutos, sino porqué pensamos que en el contexto del desarrollo de  aplicaciones en Internet escalables de ciertas dimensiones y cambio constante, la &lt;em&gt;FP&lt;/em&gt; puede ayudar mucho a entender el código y a aumentar su rendimiento de forma, creemos, más sencilla que la &lt;em&gt;OOP&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Volviendo a la pregunta, ¿es &lt;a href="https://arrow-kt.io/docs/apidocs/arrow-core/arrow.core/-validated/"&gt;Validated&lt;/a&gt; un &lt;a href="https://en.wikipedia.org/wiki/Applicative_functor"&gt;Applicative&lt;/a&gt;? &lt;/p&gt;

&lt;p&gt;La única forma de demostrarlo es haciendo una verificación formal, comprobando que &lt;em&gt;Validated&lt;/em&gt; cumple con las leyes matemáticas cómo &lt;a href="https://en.wikipedia.org/wiki/Functor"&gt;Functor&lt;/a&gt; así cómo también cumple con las leyes matemáticas de &lt;a href="https://en.wikipedia.org/wiki/Applicative_functor"&gt;Applicative Functor&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Hemos creado un pequeño test &lt;a href="https://github.com/AdevintaSpain/wonderful-freshair-app/blob/master/src/test/kotlin/com/wonderful/freshair/ValidatedAsApplicativeTest.kt"&gt;ValidatedAsApplicativeTest&lt;/a&gt; con &lt;a href="https://kotest.io/"&gt;Kotest&lt;/a&gt; para comprobar estas propiedades. De todos modos, &lt;em&gt;Validated&lt;/em&gt; además de ser un &lt;em&gt;Functor&lt;/em&gt; y un &lt;em&gt;Applicative&lt;/em&gt;, es también un &lt;em&gt;Type Constructor&lt;/em&gt;, concretamente construye &lt;em&gt;Coproducts&lt;/em&gt; o &lt;em&gt;Sum types&lt;/em&gt; del tipo &lt;em&gt;Valid&lt;/em&gt; o &lt;em&gt;Invalid&lt;/em&gt; para pares de tipos concretos. Los test que hemos hecho utilizan  &lt;code&gt;Validated&amp;lt;Nothing, String?&amp;gt;&lt;/code&gt; y &lt;code&gt;ValidatedNel&amp;lt;String?, String?&amp;gt;&lt;/code&gt;. Ésta es una desventaja que tiene la programación en Kotlin con las matemáticas. Debo crear instancias concretas de tipos para poder utilizarlos en test y por tanto, estoy comprobando únicamente esas leyes para esos tipos concretos, y no para todos los tipos que &lt;em&gt;Validated&lt;/em&gt; puede construir.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/AdevintaSpain/wonderful-freshair-app/blob/master/src/test/kotlin/com/wonderful/freshair/ValidatedAsApplicativeTest.kt#L25"&gt;Conservación de los morfismos de identidad.&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="s"&gt;"Validated functor must preserve identity arrows"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;checkAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;genNullableString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="nf"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="nf"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invalid&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="nf"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;invalid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/AdevintaSpain/wonderful-freshair-app/blob/master/src/test/kotlin/com/wonderful/freshair/ValidatedAsApplicativeTest.kt#L32"&gt;Conservación de la composición de morfismos.&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="s"&gt;"Validated functor must preserve function composition"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;checkAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;genNullableString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;f&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"PRE-APPENDED${b}"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;g&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"${b}POST-APPENDED"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;invalid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invalid&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;mapLeft&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/AdevintaSpain/wonderful-freshair-app/blob/master/src/test/kotlin/com/wonderful/freshair/ValidatedAsApplicativeTest.kt#L41"&gt;Identidad.&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="s"&gt;"Validated applicative must satisfy identity law"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;checkAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;genValidated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;validated&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;validatedId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Validated&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lift&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NonEmptyList&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?&amp;gt;{&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;validatedId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="n"&gt;validated&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/AdevintaSpain/wonderful-freshair-app/blob/master/src/test/kotlin/com/wonderful/freshair/ValidatedAsApplicativeTest.kt#L48"&gt;Homomorfismo.&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="s"&gt;"Validated applicative must satisfy homomorphism law"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;checkAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;genNullableString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;f&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"PRE-APPENDED${b}"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;validatedF&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Validated&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lift&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Nothing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;validatedF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/AdevintaSpain/wonderful-freshair-app/blob/master/src/test/kotlin/com/wonderful/freshair/ValidatedAsApplicativeTest.kt#L56"&gt;Intercambio.&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt; &lt;span class="s"&gt;"Validated applicative must satisfy interchange law"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;checkAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;genNullableString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;f&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"PRE-APPENDED${b}"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;validatedF1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Validated&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lift&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Nothing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;validatedF2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Validated&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lift&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Nothing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?)&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;validatedF1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="nf"&gt;validatedF2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/AdevintaSpain/wonderful-freshair-app/blob/master/src/test/kotlin/com/wonderful/freshair/ValidatedAsApplicativeTest.kt#L65"&gt;Composición.&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="s"&gt;"Validated applicative must satisfy composition law"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;checkAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;genNullableString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;f&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"PRE-APPENDED${b}"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;g&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"${b}POST-APPENDED"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;validatedF1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Validated&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lift&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Nothing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;validatedF2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Validated&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lift&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Nothing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validatedF2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validatedF1&lt;/span&gt;&lt;span class="p"&gt;))(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="n"&gt;shouldBe&lt;/span&gt; &lt;span class="nf"&gt;validatedF1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;validatedF2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hemos utilizado la función &lt;em&gt;lift&lt;/em&gt; de &lt;em&gt;Validated&lt;/em&gt; para comprobar estas leyes, inspirados en la definición formal de estas leyes en &lt;a href="https://www.haskell.org/"&gt;Haskell&lt;/a&gt;. Sin embargo, preguntando a la comunidad de &lt;a href="https://arrow-kt.io/"&gt;Arrow&lt;/a&gt; nos comentaron que aunque son correctas, sería mas idiomático verificarlas usando la función &lt;em&gt;zip&lt;/em&gt; de &lt;em&gt;Validated&lt;/em&gt;.  Es un ejercicio que queda pendiente.Y si queréis contribuir con ello haciendo una &lt;a href="https://github.com/AdevintaSpain/wonderful-freshair-app"&gt;PR a nuestro repo&lt;/a&gt;  será más que bienvenida.&lt;/p&gt;

&lt;p&gt;Encontrarás las verificaciones formales matemáticas de Functor y Applicative en &lt;a href="https://github.com/BartoszMilewski/Publications/blob/master/TheDaoOfFP/DaoFP.pdf"&gt;The Dao of Functional Programming&lt;/a&gt; de @BartoszMilewski. Libro que te recomiendo si te quieres introducir en &lt;em&gt;Teoría de categorías&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://careers.adevinta.es/ofertas/?search=backend&amp;amp;stc=aff-blog%20dev.to-%C2%BFEs%20Validated%20un%20Applicative%3F"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--diOTQln3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v6l1ob19ju6ol8ksv356.png" alt="Ofertas Backend" width="880" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>arrow</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Either vs Try (vs Result)</title>
      <dc:creator>Ivan Lorenz</dc:creator>
      <pubDate>Tue, 16 Nov 2021 12:59:34 +0000</pubDate>
      <link>https://dev.to/adevintaspain/either-vs-try-vs-result-2efd</link>
      <guid>https://dev.to/adevintaspain/either-vs-try-vs-result-2efd</guid>
      <description>&lt;p&gt;Preguntas y respuestas sobre las &lt;a href="https://dev.to/rogervinas/series/14723"&gt;sesiones&lt;/a&gt; &lt;em&gt;live coding&lt;/em&gt; de &lt;a href="https://arrow-kt.io/"&gt;Arrow&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;La siguiente pregunta fue realizada durante la &lt;a href="https://dev.to/adevintaspain/gestion-de-errores-funcional-con-kotlin-y-arrow-2a93"&gt;segunda sesión&lt;/a&gt;. Os dejamos también el enlace directo a la &lt;a href="https://github.com/AdevintaSpain/wonderful-freshair-app/discussions/5"&gt;discusión en Github&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pregunta
&lt;/h2&gt;

&lt;p&gt;Para captura de excepciones presentasteis &lt;code&gt;Either&amp;lt;L,R&amp;gt;&lt;/code&gt;.  Arrow incluye &lt;a href="https://arrow-kt.io/docs/0.10/apidocs/arrow-core-data/arrow.core/-try/"&gt;&lt;code&gt;Try&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/a&gt; y la librería standard de Kotlin incluye &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-result/"&gt;&lt;code&gt;Result&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Arrow ya tiene &lt;code&gt;Try&lt;/code&gt; marcada como &lt;em&gt;deprecated&lt;/em&gt; porque no se alinea del todo con los principios de programación (paradigma?) que promueve Arrow.&lt;/p&gt;

&lt;p&gt;La lib estándar de Kotlin incluye &lt;code&gt;Result&lt;/code&gt; que parece una mezcla de &lt;code&gt;Try&lt;/code&gt; y &lt;code&gt;Option&lt;/code&gt;. Tampoco es demasiado limpio en mi opinión.&lt;/p&gt;

&lt;p&gt;Hoy (en relación al 23 de septiembre) Alex Nedelcu ha hecho una &lt;a href="https://twitter.com/alexelcu/status/1440978686161915907"&gt;twitter poll&lt;/a&gt; (ligeramente) relacionada con este tema.&lt;br&gt;
&lt;/p&gt;
&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--XRe3ovkD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1390028956523499521/dDCqt3d9_normal.jpg" alt="Alex Nedelcu profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Alex Nedelcu
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @alexelcu
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Are you a Try person, or a try/catch person?
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      09:57 AM - 23 Sep 2021
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1440978686161915907" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1440978686161915907" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1440978686161915907" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;
 

&lt;p&gt;Podrías desarrollar los pros/cons de usar &lt;code&gt;Either&lt;/code&gt; en comparación con las otras opciones que existen?&lt;/p&gt;

&lt;h2&gt;
  
  
  Respuesta
&lt;/h2&gt;

&lt;p&gt;Primero déjame establecer el contexto de nuestra respuesta, porque sin un contexto no hay explicación que se sostenga. En mi equipo en &lt;a class="mentioned-user" href="https://dev.to/adevintaeng"&gt;@adevintaeng&lt;/a&gt;
 desarrollamos aplicaciones distribuidas con &lt;a href="https://kotlinlang.org/"&gt;Kotlin&lt;/a&gt;. &lt;em&gt;Hemos encontrado valor en usar métodos monádicos en programación OO&lt;/em&gt;. Nos interesa la componibilidad y la expresividad de tipos como &lt;code&gt;Either&amp;lt;L,R&amp;gt;&lt;/code&gt; y los patrones de gestión de errores que facilita, cómo mostramos en esta segunda sesión. Desarrollando sistemas distribuidos sabemos que la gestión de errores, su diseño y su evolución, es la clave para crear aplicaciones resilientes y tolerantes al fallo.&lt;/p&gt;

&lt;p&gt;En este contexto encontramos el uso de la librería &lt;a href="https://arrow-kt.io/docs/core/"&gt;Arrow Core&lt;/a&gt; un perfecto compañero de viaje. Parte del trabajo de un ingeniero de software es asegurarse que las librerías que utiliza van a ser una ayuda para acelerar el desarrollo a la vez que no van a representar un problema en el futuro, como librerías no mantenidas o sin una estrategia de evolución sólida y solvente. En cuanto empezamos a utilizar Arrow &lt;code&gt;0.13.2&lt;/code&gt;, el tipo &lt;code&gt;Try&amp;lt;T&amp;gt;&lt;/code&gt; ya estaba obsoleto y eliminado desde la versión &lt;code&gt;0.11&lt;/code&gt;. Y el tipo &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; estaba siendo cuestionado por los mismos creadores de Arrow. Así que recomendaban el uso de &lt;code&gt;Either&amp;lt;L,R&amp;gt;&lt;/code&gt; desde la versión &lt;code&gt;0.13.2&lt;/code&gt; para garantizar la compatibilidad total con la primera versión general de &lt;a href="https://www.47deg.com/blog/arrow-1-0-release/"&gt;Arrow &lt;code&gt;1.0.0&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Desde el punto de vista de un programador que utiliza la librería para sus aplicaciones en producción, esta debería ser una explicación suficiente para utilizar &lt;code&gt;Either&amp;lt;L, R&amp;gt;&lt;/code&gt; frente a las otras opciones. Pero podemos elaborar más las razones. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Try&amp;lt;T&amp;gt;&lt;/code&gt; fue marcado cómo obsoleto en Arrow en el mismo momento que se decidió marcar cómo obsoleto &lt;code&gt;IO&lt;/code&gt; monad y basar la estrategia de convertir las funciones con efectos laterales en funciones puras con el uso de Kotlin &lt;code&gt;suspend&lt;/code&gt;. Marcando una función con &lt;code&gt;suspend&lt;/code&gt; la ejecución de esa función devuelve una descripción del efecto, es decir el efecto no se produce si no la provees con un contexto, en este caso una &lt;a href="https://kotlinlang.org/docs/coroutines-overview.html"&gt;&lt;code&gt;Coroutine&lt;/code&gt;&lt;/a&gt;. Si quieres profundizar más en el porqué, &lt;a href="https://arrow-kt.io/docs/effects/io/"&gt;aquí encontrarás el porque del cambio de estrategia&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Bien, que pasaba con &lt;code&gt;Try&amp;lt;T&amp;gt;&lt;/code&gt;? El primer problema es que &lt;code&gt;Try&lt;/code&gt; no podía diferir la ejecución del efecto de ningún modo y retornar únicamente una descripción del efecto porque sus constructores "evaluaban ansiosamente" - Dios, que difícil es intentar escribir en español sobre cualquier tema de ingeniería del software - a.k.a &lt;code&gt;eager evaluation&lt;/code&gt; . Puedes ampliar detalles sobre los tipos de evaluación en &lt;a href="https://dev.to/drbearhands/lazy-eager-and-greedy-evaluation-43pf"&gt;Lazy, eager and greedy evaluation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;El segundo problema es que &lt;code&gt;Try&amp;lt;T&amp;gt;&lt;/code&gt; no es seguro. Porqué? Básicamente porque puedes capturar cualquier &lt;code&gt;Throwable&lt;/code&gt; que desees. Y si quieres tener control sobre una computación concurrente o paralela en la que se usa, no querrás que &lt;code&gt;Try&amp;lt;T&amp;gt;&lt;/code&gt; pueda capturar &lt;code&gt;InterruptedException&lt;/code&gt; o &lt;code&gt;CancellationException&lt;/code&gt; entre otros.&lt;/p&gt;

&lt;p&gt;Y éste es exactamente el mismo problema con &lt;a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-result/"&gt;&lt;code&gt;Result&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/a&gt; en Kotlin. De hecho, &lt;code&gt;Result&amp;lt;T&amp;gt;&lt;/code&gt; es el tipo que se debe usar en vez de &lt;code&gt;Try&amp;lt;T&amp;gt;&lt;/code&gt; para los caso de uso que así lo requieran.&lt;/p&gt;

&lt;p&gt;Por todo esto, en Arrow se implementó &lt;a href="https://arrow-kt.io/docs/apidocs/arrow-core/arrow.core/-either/#eithercatch-exceptions"&gt;&lt;code&gt;Either.catch&lt;/code&gt;&lt;/a&gt;, que es el camino a seguir para aislar nuestro código de librerías "impuras". &lt;/p&gt;

&lt;p&gt;En cuanto a &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; hubo bastante debate al respecto sobre si eliminar su uso en beneficio de un más idiomático - en Kotlin - &lt;a href="https://kotlinlang.org/docs/null-safety.html#nullable-types-and-non-null-types"&gt;Nullable types&lt;/a&gt;, porque se apreciaba poca aportación de valor sobre esto tipos. Además se indicaba que &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt;no era más que (o si lo prefieres, es isomórfico a) &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;typealias Option&amp;lt;A&amp;gt; = Either&amp;lt;Unit, A&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pero después del &lt;a href="https://github.com/arrow-kt/arrow-core/issues/114"&gt;largo debate&lt;/a&gt; &lt;a class="mentioned-user" href="https://dev.to/raulraja"&gt;@raulraja&lt;/a&gt;
 anunció que mantendrían &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; en Arrow Core &lt;code&gt;1.0.0&lt;/code&gt; cómo así ha sido, porque existían algunos casos de uso en que todavía aportaba valor cómo con &lt;a href="https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#nulls"&gt;RxJava&lt;/a&gt; que declara &lt;code&gt;Observable&amp;lt;T&amp;gt;&lt;/code&gt; y no permite &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Cómo ves, muchas de las razones se basan en cuestiones de la programación funcional cómo &lt;code&gt;lazy evaluation&lt;/code&gt; o en cómo convertir en declarativos los efectos laterales de una función y diferir su ejecución en un entorno seguro. Nosotros todavía no estamos utilizando &lt;a href="https://arrow-kt.io/docs/fx/"&gt;&lt;code&gt;Arrow Fx&lt;/code&gt;&lt;/a&gt; ni estamos marcando nuestras funciones cómo &lt;code&gt;suspended&lt;/code&gt;, pero lo haremos si le encontramos valor para nuestros casos de usos y por supuesto, lo explicaremos en otras sesiones.&lt;/p&gt;

&lt;p&gt;Espero que haya podido aclarar un poco tus dudas. Y no dudéis en matizar o corregir algún punto que no haya explicado con claridad o que mi memoria haya hecho desviar de la verdad.  Obviamente, los que mejor pueden explicar esto son &lt;a class="mentioned-user" href="https://dev.to/raulraja"&gt;@raulraja&lt;/a&gt;
, @47deg y los &lt;a href="https://github.com/arrow-kt/arrow/graphs/contributors"&gt;contributors del proyecto Arrow&lt;/a&gt;, a los que de paso, les doy las gracias por esta magnífica librería.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://careers.adevinta.es/ofertas/?search=backend&amp;amp;stc=aff-blog%20dev.to-Either%20vs%20Try%20%28vs%20Result%29"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YqDKTZN6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nj85cjrphaqyozm0gq6d.png" alt="Ofertas Backend" width="880" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>arrow</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
