<?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: David Geirola</title>
    <description>The latest articles on DEV Community by David Geirola (@geirolz).</description>
    <link>https://dev.to/geirolz</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%2F212409%2Ffa8e677c-193a-43e9-924b-0e36ff75c438.jpeg</url>
      <title>DEV Community: David Geirola</title>
      <link>https://dev.to/geirolz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/geirolz"/>
    <language>en</language>
    <item>
      <title>Secret values in Scala</title>
      <dc:creator>David Geirola</dc:creator>
      <pubDate>Tue, 13 Feb 2024 13:49:22 +0000</pubDate>
      <link>https://dev.to/geirolz/secret-values-in-scala-1d7g</link>
      <guid>https://dev.to/geirolz/secret-values-in-scala-1d7g</guid>
      <description>&lt;h2&gt;
  
  
  Preface
&lt;/h2&gt;

&lt;p&gt;One of the most important topics in IT is surely the security, it's so complicated and intriguing that, either you love it or you hate it, but we can't help taking care of it. Nowadays, in a society based on computers and applications, crackers attacks are very concrete and dangerous.  &lt;br&gt;
In my opinion, when we talk about IT security, it is always better to overestimate the risk and have a large margin of tolerance. &lt;br&gt;
The (hard) trade-off we have to make is that the solution is usable, has good performance, and is safe.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Often, it is not a single solution that makes something safe; it is the sum of several approaches that mitigate the risk.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  History
&lt;/h2&gt;

&lt;p&gt;It has been a while since I had my first idea for a library that would help developers securely manage secret values within their applications. Originally, I started with a very simple wrapper of &lt;code&gt;String&lt;/code&gt; to avoid unwanted printing or logging of the secret value, then I created my own application &lt;a href="https://github.com/geirolz/toolkit"&gt;toolkit&lt;/a&gt; where I added a dedicated module with a minimal version of the &lt;code&gt;Secret&lt;/code&gt; type. &lt;/p&gt;

&lt;p&gt;Step by step, iteration by iteration, I abandoned the &lt;a href="https://github.com/geirolz/toolkit"&gt;toolkit&lt;/a&gt; module in favor of a dedicated library for handling secrets.&lt;br&gt;
In this article, I want to briefly introduce you to my new library, explain how it works, and explain why you should use it in your projects. &lt;br&gt;
As I just said, this is the latest iteration of this idea, not the final one, and since I am now releasing it as a standalone library, I hope to get feedback and ideas to make it even better. &lt;/p&gt;

&lt;p&gt;Secret library github page&lt;br&gt;
&lt;a href="https://github.com/geirolz/secret"&gt;https://github.com/geirolz/secret&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Read this interesting article which inspired my about this library&lt;br&gt;
&lt;a href="https://westonal.medium.com/protecting-strings-in-jvm-memory-84c365f8f01c"&gt;https://westonal.medium.com/protecting-strings-in-jvm-memory-84c365f8f01c&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  The problem of secrets in applications
&lt;/h2&gt;

&lt;p&gt;I believe everyone who is reading this article already knows about these problems. &lt;br&gt;
Just to be pragmatic, I'll use one of my favorite tools, a list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hard-coded secrets&lt;/li&gt;
&lt;li&gt;Unwanted printing and logging of secrets value&lt;/li&gt;
&lt;li&gt;Memory leaks due to cracker attacks (e.g. JVM Heap dump)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I will briefly review these 3 problems to give you a broader context and to share the ideas behind my library. If you are not interested in this part, you can skip to the end of the article for the introduction to the library, or you can look directly at the &lt;a href="https://github.com/geirolz/secret"&gt;library page on github&lt;/a&gt;. &lt;/p&gt;
&lt;h3&gt;
  
  
  Hard-coded secrets
&lt;/h3&gt;

&lt;p&gt;Below is an image explaining how secure it is to have one's datacenter fenced and guarded by armed guards, a thousand layers of software security, and hard-coded secrets. &lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5hw04ijc154tcc3e80xl.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5hw04ijc154tcc3e80xl.jpeg" alt="weak security" width="735" height="549"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are several approaches to avoid this bad practice; I won't go through them in this article, but just to give you a tip, if you are using Kubernetes, you could use &lt;a href="https://kubernetes.io/docs/concepts/configuration/secret/"&gt;Secrets&lt;/a&gt;; similar to &lt;a href="https://kubernetes.io/docs/concepts/configuration/configmap/"&gt;ConfigMaps&lt;/a&gt; but specifically intended to hold confidential data. &lt;/p&gt;

&lt;p&gt;Then you can mount secrets as a volume, inject them as environment variables, or synchronously access the vault.&lt;/p&gt;

&lt;p&gt;Let me know if you know more methods to solve this! &lt;/p&gt;
&lt;h3&gt;
  
  
  Printing and logging
&lt;/h3&gt;

&lt;p&gt;Unfortunately, this problem doesn't have a definitive solution. Common sense and education prevent most of the cases, but we are humans, and we can easily get distracted.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fseasa8ky5g16rhqr2nak.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fseasa8ky5g16rhqr2nak.jpg" alt="Image description" width="700" height="807"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A very simple solution would be wrapping the secret value overriding the &lt;code&gt;toString&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Secret&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AnyVal&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt;
  &lt;span class="kt"&gt;override&lt;/span&gt; &lt;span class="kt"&gt;toString:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"** SECRET **"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cool! But the following example could easily happen&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Config&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;databasePass&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Secret&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initDb&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pass&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Unit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;???&lt;/span&gt;

&lt;span class="c1"&gt;//usage&lt;/span&gt;
&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;???&lt;/span&gt;
&lt;span class="nf"&gt;initDb&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;databasePass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;value&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem is that the &lt;code&gt;initDb&lt;/code&gt; method has full access to the secret value, and someone could unintentionally log or print it. The easy solution would be to pass the type &lt;code&gt;Secret&lt;/code&gt; instead of the &lt;code&gt;String&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;While one improvement for the &lt;code&gt;Secret&lt;/code&gt; type might be to make the API a little more difficult to use to force the user to think.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Secret&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt;
  &lt;span class="kt"&gt;override&lt;/span&gt; &lt;span class="kt"&gt;toString:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"** SECRET **"&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;T&lt;/span&gt;&lt;span class="o"&gt;](&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;T&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not a solution; you can easily bypass it, but it makes it a little more difficult (sum of approaches). &lt;/p&gt;

&lt;p&gt;If you do this, you deserve a firing letter :)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;pass&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;secretPass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;use&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;identity&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Memory leaks
&lt;/h3&gt;

&lt;p&gt;Ok, let's start with the assumption that if someone has access to your application environment, this is not the only problem you have, but surely we can make the lives of our friends crackers a bit harder.&lt;br&gt;
Here we discuss the JVM heap dump attack, a common attack to steal secrets and sensible data from an application.&lt;/p&gt;

&lt;p&gt;Basically, the attack consists of creating a snapshot of the JVM heap and analyzing it in order to find sensible information. &lt;/p&gt;

&lt;p&gt;To work around this problem, we can use a kind of &lt;code&gt;ByteBuffer&lt;/code&gt; called &lt;code&gt;direct&lt;/code&gt; that allocates the data directly to the memory, outside the JVM heap.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="nv"&gt;ByteBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;allocateDirect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytesCapacity&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The heap will only contain the memory addresses of the byte buffer.&lt;/p&gt;

&lt;p&gt;To improve security a bit, we can also obfuscate the bytes we are allocating by using some strategies, the most common of which is the use of the &lt;code&gt;xor&lt;/code&gt; operator. &lt;br&gt;
Xor is simple, fast, and isomorphic. Xor is not secure because it is not a cryptographic algorithm, but it is sufficient if we add up all these tricks. &lt;/p&gt;

&lt;p&gt;Once finished with the secret byte buffer, you can overwrite the value with &lt;code&gt;0&lt;/code&gt; and cancel the pointer to avoid unnecessary leaks. Secrets are usually used at startup to build connectors or instances; there is no need to keep them in memory forever unnecessarily. &lt;/p&gt;

&lt;h2&gt;
  
  
  Secret library
&lt;/h2&gt;

&lt;p&gt;Well, I've created a library called &lt;a href="https://github.com/geirolz/secret"&gt;Secret&lt;/a&gt; (very creative) that implements what you just read in a type named &lt;code&gt;Secret&lt;/code&gt;. &lt;br&gt;
It supports direct byte buffers, xor-ed values (all primitive types), secure destruction, map and flatMap.&lt;br&gt;
With the special type &lt;code&gt;DeferredSeret&lt;/code&gt; you can define a secret that is acquired and then destroyed whenever it is accessed (for example, a remote call to get the value from a vault). &lt;/p&gt;

&lt;p&gt;It has integration modules for &lt;a href="https://github.com/geirolz/secret?tab=readme-ov-file#cats-effect"&gt;cats-effect&lt;/a&gt;, &lt;a href="https://github.com/geirolz/secret?tab=readme-ov-file#pureconfig"&gt;pureconfig&lt;/a&gt;, &lt;a href="https://github.com/geirolz/secret?tab=readme-ov-file#ciris"&gt;ciris&lt;/a&gt; and &lt;a href="https://github.com/geirolz/secret?tab=readme-ov-file#typesafe-config"&gt;Typesafe Config&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also extend it by defining a custom algorithm to use instead of xor (default). Check the &lt;a href="https://github.com/geirolz/secret?tab=readme-ov-file#custom-obfuscation-strategy-algebra"&gt;documentation&lt;/a&gt; if you are interested. &lt;/p&gt;

&lt;p&gt;As I wrote in the README, &lt;code&gt;Secret&lt;/code&gt; library does its best to avoid leaking information in memory and in the code, BUT an attack is always possible, and I don't give any certainties or guarantees about security using this library; you use it at your own risk. The code is open-sourced; you can check the implementation and make your decision consciously. I'll do my best to improve the security and documentation of this project.&lt;/p&gt;

&lt;p&gt;Let me know what you think about this article and this project! Comments, feedback, PRs, and discussions are welcome.&lt;br&gt;
If you like the library, please consider leaving a star on Github to support it! &lt;/p&gt;

</description>
      <category>scala</category>
      <category>configuration</category>
      <category>security</category>
      <category>development</category>
    </item>
    <item>
      <title>Rules evaluation in Scala with Erules and Cats</title>
      <dc:creator>David Geirola</dc:creator>
      <pubDate>Mon, 13 Nov 2023 11:15:50 +0000</pubDate>
      <link>https://dev.to/geirolz/rules-evaluation-in-scala-with-erules-and-cats-2png</link>
      <guid>https://dev.to/geirolz/rules-evaluation-in-scala-with-erules-and-cats-2png</guid>
      <description>&lt;h1&gt;
  
  
  Introduction to Erules Library: A Practical Guide
&lt;/h1&gt;

&lt;p&gt;Erules is a lightweight, simple, and functional Scala library for rule evaluation. In this article, we will explore how to use this library to define and evaluate rules efficiently. Follow step-by-step for a detailed and hands-on understanding of use cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Erules?
&lt;/h2&gt;

&lt;p&gt;Erules is a library that provides a rule evaluation engine in Scala. It is designed to be straightforward, typed, and functional, leveraging the power of Cats core. With Erules, you can define rules clearly and evaluate them on various data types concisely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Import the Library
&lt;/h2&gt;

&lt;p&gt;To get started, add Erules as a dependency to your Scala project. You can do this in the &lt;code&gt;build.sbt&lt;/code&gt; file with the following declaration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="n"&gt;libraryDependencies&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s"&gt;"com.github.geirolz"&lt;/span&gt; &lt;span class="o"&gt;%%&lt;/span&gt; &lt;span class="s"&gt;"erules-core"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="s"&gt;"0.1.0"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure to check the &lt;a href="https://mvnrepository.com/artifact/com.github.geirolz/erules-core"&gt;Maven page&lt;/a&gt; for the latest version.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Define Data Classes
&lt;/h2&gt;

&lt;p&gt;Before defining rules, declare the data classes on which you want to apply them. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Country&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Age&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Citizenship&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;country&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Country&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Age&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;citizenship&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Citizenship&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Write Rules
&lt;/h2&gt;

&lt;p&gt;Now you can start defining the rules you want to apply to the data. &lt;br&gt;
Each Rule must have a unique name and can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pure&lt;/strong&gt;: a pure function that takes a value and returns a &lt;code&gt;RuleVerdict&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Effectful&lt;/strong&gt;: a function that takes a value and returns a &lt;code&gt;F[RuleVerdict]&lt;/code&gt; where &lt;code&gt;F&lt;/code&gt; is a monad.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are several ways to define a rule:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;apply&lt;/strong&gt;: defines a complete rule from &lt;code&gt;T&lt;/code&gt; to &lt;code&gt;F[RuleVerdict]&lt;/code&gt; ( or &lt;code&gt;Id&lt;/code&gt; for Pure Rules)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;matchOrIgnore&lt;/strong&gt;: defines a partial function from &lt;code&gt;T&lt;/code&gt; to &lt;code&gt;F[RuleVerdict]&lt;/code&gt; ( or &lt;code&gt;Id&lt;/code&gt; for Pure Rules). If the function is not defined for the input value, the rule is ignored.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;const&lt;/strong&gt;: defines a rule that always returns the same &lt;code&gt;RuleVerdict&lt;/code&gt; (e.g. &lt;code&gt;Allow&lt;/code&gt; or &lt;code&gt;Deny&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;failed&lt;/strong&gt;: defines a rule that always fails with an exception&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;assert&lt;/strong&gt;: defines a rule from &lt;code&gt;T&lt;/code&gt; to &lt;code&gt;F[Boolean]&lt;/code&gt; ( or &lt;code&gt;Id&lt;/code&gt; for Pure Rules) and returns &lt;code&gt;Allow&lt;/code&gt; for &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;Deny&lt;/code&gt; for &lt;code&gt;false&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;assertNot&lt;/strong&gt;: defines a rule from &lt;code&gt;T&lt;/code&gt; to &lt;code&gt;F[Boolean]&lt;/code&gt; ( or &lt;code&gt;Id&lt;/code&gt; for Pure Rules) and returns &lt;code&gt;Allow&lt;/code&gt; for &lt;code&gt;false&lt;/code&gt; or &lt;code&gt;Deny&lt;/code&gt; for &lt;code&gt;true&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;fromBooleanF&lt;/strong&gt;: defines a rule from &lt;code&gt;T&lt;/code&gt; to &lt;code&gt;F[Boolean]&lt;/code&gt; ( or &lt;code&gt;Id&lt;/code&gt; for Pure Rules) where you can specify the behavior for &lt;code&gt;true&lt;/code&gt; and &lt;code&gt;false&lt;/code&gt; values.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For instance, let's say you want to check if a person is an adult and has UK citizenship:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;erules.Rule&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;erules.PureRule&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;erules.RuleVerdict.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;cats.data.NonEmptyList&lt;/span&gt;

&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;checkCitizenship&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;PureRule&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Citizenship&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt;
  &lt;span class="nc"&gt;Rule&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Check UK citizenship"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Citizenship&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Country&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"UK"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;Allow&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;withoutReasons&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;Deny&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;because&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Only UK citizenship is allowed!"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;checkAdultAge&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;PureRule&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Age&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt;
  &lt;span class="nc"&gt;Rule&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Check Age &amp;gt;= 18"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Age&lt;/span&gt; &lt;span class="kt"&gt;if&lt;/span&gt; &lt;span class="kt"&gt;a.value&lt;/span&gt; &lt;span class="kt"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="err"&gt;18&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;Allow&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;withoutReasons&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;Deny&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;because&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Only &amp;gt;= 18 age are allowed!"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;allPersonRules&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;NonEmptyList&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;PureRule&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;NonEmptyList&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
  &lt;span class="nv"&gt;checkCitizenship&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;targetInfo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"citizenship"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="py"&gt;contramap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;citizenship&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
  &lt;span class="nv"&gt;checkAdultAge&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;targetInfo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"age"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="py"&gt;contramap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;age&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;N.B. Importing even the &lt;code&gt;erules-generic&lt;/code&gt; you can use a macro to auto-generate the target info using the &lt;code&gt;contramapTarget&lt;/code&gt; method. &lt;br&gt;
&lt;code&gt;contramapTarget&lt;/code&gt; applies contramap and derives the target info by the contramap parameter. &lt;br&gt;
The contramap parameter must be inline and have the following form: &lt;code&gt;_.bar.foo.test&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 4: Use the Evaluation Engine
&lt;/h2&gt;

&lt;p&gt;Now that you've defined the rules, you can use the evaluation engine to check them.&lt;br&gt;
You can run the engine in two ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;denyAllNotAllowed&lt;/strong&gt;: to deny all is not explicitly allowed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;allowAllNotDenied&lt;/strong&gt;: to allow all is not explicitly denied.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Moreover, you can choose to run the engine in a pure way( with pure rules ) or in a monadic way (e.g. IO) using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;seqEvalPure&lt;/strong&gt;: to run the engine in a pure way with pure rules. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;seqEval&lt;/strong&gt;: to sequentially run the engine in a monadic way.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;parEval&lt;/strong&gt;: to parallel run the engine in a monadic way.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;parEvalN&lt;/strong&gt;: to parallel run the engine in a monadic way with a fixed parallelism level.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;erules.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;erules.implicits.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;cats.Id&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;cats.effect.IO&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;cats.effect.unsafe.implicits.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;

&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;person&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"John"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Doe"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Age&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="nc"&gt;Citizenship&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Country&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"UK"&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt;

&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;EngineResult&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt;
  &lt;span class="nc"&gt;RulesEngine&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;withRules&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Id&lt;/span&gt;, &lt;span class="kt"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;](&lt;/span&gt;&lt;span class="n"&gt;allPersonRules&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;denyAllNotAllowed&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;seqEvalPure&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;

&lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;unsafeRunSync&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="py"&gt;asReport&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Erules provides a powerful yet simple way to define and evaluate rules in Scala. By following these steps, you can integrate Erules into your projects for efficient and type-safe rule evaluation.&lt;/p&gt;

&lt;p&gt;For more details, check out the &lt;a href="https://github.com/geirolz/erules"&gt;Erules GitHub Repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I would love to receive feedback, so if you want to let me know what you think of this library!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>scala</category>
      <category>tutorial</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Semantic of a functional app in Scala</title>
      <dc:creator>David Geirola</dc:creator>
      <pubDate>Mon, 19 Jun 2023 22:17:12 +0000</pubDate>
      <link>https://dev.to/geirolz/semantic-of-a-functional-app-in-scala-4cn3</link>
      <guid>https://dev.to/geirolz/semantic-of-a-functional-app-in-scala-4cn3</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Functional applications offer numerous benefits in modern software development. They enhance testability, modularity, and composability, leading to more maintainable and scalable codebases. In this article, we'll explore the syntax and semantics of functional applications and introduce the app-toolkit library—a powerful tool for building functional applications more efficiently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Syntax and Semantic of an App
&lt;/h2&gt;

&lt;p&gt;At its core, an app can be represented as a function that takes an input (&lt;code&gt;I&lt;/code&gt;) and produces an output (&lt;code&gt;O&lt;/code&gt;). By incorporating side effects, we extend this representation to &lt;code&gt;I =&amp;gt; F[O]&lt;/code&gt;, where &lt;code&gt;F[_]&lt;/code&gt; denotes the ability to handle side effects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;To build an app, we rely on resources such as app information, input arguments, a logger, and configuration settings. &lt;/p&gt;

&lt;p&gt;With this concept in mind, we can merge these resources with the input (&lt;code&gt;I&lt;/code&gt;) since the only input we have are the app arguments, resulting in:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;(AppInfo, F[Config], Args, F[Logger], F[OtherResources]) =&amp;gt; F[O]&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Dependencies
&lt;/h2&gt;

&lt;p&gt;Dependencies represent application-specific services and repositories used in the app's logic.&lt;/p&gt;

&lt;p&gt;Combining resources and dependencies, we arrive at:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;(AppInfo, F[Config], Args, F[Logger], F[OtherResources]) =&amp;gt; (AppInfo, Config, Args, Logger, OtherResources, F[Dependencies]) =&amp;gt; F[O]&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because we need resources to build the dependencies and we need dependencies to build the app logic.&lt;br&gt;
Dependencies also includes the resources.&lt;/p&gt;
&lt;h2&gt;
  
  
  Provided services
&lt;/h2&gt;

&lt;p&gt;Now, let's imagine that given all the resources and dependencies, we can define a list of tasks to run in parallel (including never-terminating tasks like an HTTP server). &lt;/p&gt;

&lt;p&gt;Thus, the final definition of the app logic &lt;code&gt;F[O]&lt;/code&gt; is actually the result of the parallel execution of all the provided services, which are expressed as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;AppDependencies =&amp;gt; F[List[Any]]&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Giving an example a service that provide an HTTP server is just a single never-ending task app.&lt;/p&gt;

&lt;p&gt;An app that provide an HTTP server and consume from a Kafka topic is 2 parallel tasks app. &lt;/p&gt;
&lt;h2&gt;
  
  
  Flattening
&lt;/h2&gt;

&lt;p&gt;We have zoomed inside the app's semantics to better understand its parts, but in the end, the app can be typed as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;F[Unit]&lt;/code&gt; or &lt;code&gt;F[ExitCode]&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since the output of the app must be delivered through the provided services, the output will always be &lt;code&gt;Unit&lt;/code&gt; or &lt;code&gt;ExitCode&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The app consists of multiple steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Loading resources&lt;/li&gt;
&lt;li&gt;Building dependencies&lt;/li&gt;
&lt;li&gt;App logic: executing parallel tasks&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  App-toolkit
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/geirolz/toolkit"&gt;https://github.com/geirolz/toolkit&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;App-toolkit is a lightweight and functional non-intrusive library for building typed and declarative Scala applications with managed resources and dependencies. It has been developed with the aforementioned concepts in mind. It provides a nice syntax for defining and building applications, and it manages the resources, allowing you to focus on the important parts of the application.&lt;/p&gt;

&lt;p&gt;Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;cats.effect.&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;ExitCode&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;IOApp&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.geirolz.app.toolkit.App&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.geirolz.app.toolkit.logger.ToolkitLogger&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.geirolz.app.toolkit.error.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;

&lt;span class="k"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt; &lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;IOApp&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;ExitCode&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt;
    &lt;span class="nc"&gt;App&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;withInfo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nv"&gt;SimpleAppInfo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;string&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
          &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"app-toolkit"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.0.1"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;scalaVersion&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"2.13.10"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;sbtVersion&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1.8.0"&lt;/span&gt;
        &lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;withLogger&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;ToolkitLogger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;console&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;](&lt;/span&gt;&lt;span class="k"&gt;_&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;withConfigLoader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;pure&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Config&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"localhost"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;dependsOn&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;AppDependencyServices&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;_&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;provideOne&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deps&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;// Kafka consumer&lt;/span&gt;
        &lt;span class="nv"&gt;deps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;dependencies&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;kafkaConsumer&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;consumeFrom&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"test-topic"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;evalTap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;deps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="s"&gt;"Received record $record"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;compile&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;drain&lt;/span&gt;
      &lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;beforeRun&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CUSTOM PRE-RUN"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;onFinalize&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CUSTOM END"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;In this article, we explored the syntax and semantics of functional applications. We viewed applications as functions with inputs and outputs, considering side effects with the &lt;code&gt;F[_]&lt;/code&gt; type. &lt;/p&gt;

&lt;p&gt;Resources and dependencies played crucial roles in building and executing these applications. We also introduced the app-toolkit, a lightweight and functional library that simplifies the development of typed and declarative Scala applications. &lt;/p&gt;

&lt;p&gt;By leveraging functional programming principles and tools like app-toolkit, developers can create scalable and reliable applications. Understanding the syntax and semantics of functional applications empowers developers to deliver high-quality user experiences.&lt;/p&gt;

</description>
      <category>scala</category>
      <category>functional</category>
      <category>microservices</category>
      <category>programming</category>
    </item>
    <item>
      <title>Compile-time safe models separation in Scala</title>
      <dc:creator>David Geirola</dc:creator>
      <pubDate>Sun, 12 Dec 2021 22:28:29 +0000</pubDate>
      <link>https://dev.to/geirolz/compile-time-safe-model-layers-separation-in-scala-9ac</link>
      <guid>https://dev.to/geirolz/compile-time-safe-model-layers-separation-in-scala-9ac</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/geirolz/scope" rel="noopener noreferrer"&gt;https://github.com/geirolz/scope&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Every code architecture relies on developers common sense and accuracy, erring is human, in some cases, the compiler can help us&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Let's take a persistence layer as an example.&lt;br&gt;
You don't want that the &lt;code&gt;Entity&lt;/code&gt; class model, used in the persistence layer, is used in the domain or even worse as REST contract. You want to separate those concepts using different models for each layer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhe9vamrfs52kpx3smihj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhe9vamrfs52kpx3smihj.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Mapper approach
&lt;/h2&gt;

&lt;p&gt;To achieve this you need a &lt;code&gt;Mapper&lt;/code&gt; to convert the model from one scope to another and vice-versa(when needed). &lt;/p&gt;

&lt;p&gt;This Mapper can be done using a separated object, or better, defining a method into the companion object of the model, keeping the domain model clean. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;

&lt;span class="c1"&gt;//persistence&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserEntity&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;UserEntity&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;toDomain&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UserEntity&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;???&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;//domain&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;//endpoint&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserContract&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;UserContract&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fromDomain&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UserContract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;???&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Advantages
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;It's trivial&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Problems
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Bad composability (especially when the mapper is effectful)&lt;/li&gt;
&lt;li&gt;No guarantee that the users will use the mappers in the right scope&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Functional approach with Kleisli
&lt;/h2&gt;

&lt;p&gt;From a functional programming point of view, this mapper is a simple morphism &lt;code&gt;A =&amp;gt; B&lt;/code&gt;, that becomes &lt;code&gt;A =&amp;gt; F[B]&lt;/code&gt; if we want allowing effects.&lt;/p&gt;

&lt;p&gt;This is a &lt;a href="https://typelevel.org/cats/datatypes/kleisli.html" rel="noopener noreferrer"&gt;&lt;code&gt;Kleisli[F, A, B]&lt;/code&gt;&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;So, let's improve our above solution using Kleisli.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;

&lt;span class="c1"&gt;//persistence&lt;/span&gt;
&lt;span class="k"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;UserEntity&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;toDomain&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Kleisli&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Id&lt;/span&gt;, &lt;span class="kt"&gt;UserEntity&lt;/span&gt;, &lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="o"&gt;???&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;//endpoint&lt;/span&gt;
&lt;span class="k"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;UserContract&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;fromDomain&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Kleisli&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Id&lt;/span&gt;, &lt;span class="kt"&gt;User&lt;/span&gt;, &lt;span class="kt"&gt;UserContract&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="o"&gt;???&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Advantages
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Composability, even with effects is simpler &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Problems
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;No guarantee that the users will use the mappers in the right scope&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Functional approach with Scope
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/geirolz/scope" rel="noopener noreferrer"&gt;https://github.com/geirolz/scope&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/geirolz/scope" rel="noopener noreferrer"&gt;&lt;code&gt;Scope&lt;/code&gt;&lt;/a&gt; is a lightweight library to enforce the model layer separation at compile-time.&lt;br&gt;
To do this, &lt;code&gt;Scope&lt;/code&gt; simply verify the presence of an implicit Scope that corresponds to the Scope of the mapper. &lt;/p&gt;

&lt;p&gt;So, there are two main actor in scope:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/geirolz/scope/blob/main/core/src/main/scala/scope/ModelMapperK.scala" rel="noopener noreferrer"&gt;&lt;code&gt;ModelMapperK&lt;/code&gt;&lt;/a&gt; a type class to define a scoped model mapper &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/geirolz/scope/blob/main/core/src/main/scala/scope/TypedScopeContext.scala" rel="noopener noreferrer"&gt;&lt;code&gt;TypedScopeContext&lt;/code&gt;&lt;/a&gt; a type to describe an available scope&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/geirolz/scope/blob/main/core/src/main/scala/scope/ScopeContext.scala" rel="noopener noreferrer"&gt;&lt;code&gt;ScopeContext&lt;/code&gt;&lt;/a&gt; a type to describe an available untyped scope&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/geirolz/scope/blob/main/core/src/main/scala/scope/Scope.scala" rel="noopener noreferrer"&gt;&lt;code&gt;Scope&lt;/code&gt;&lt;/a&gt; an ADT to define available scopes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For pure mappers, there is &lt;a href=""&gt;&lt;code&gt;ModelMapper[S &amp;lt;: Scope, A, B]&lt;/code&gt;&lt;/a&gt; which is a type alias to &lt;a href="https://github.com/geirolz/scope/blob/main/core/src/main/scala/scope/ModelMapperK.scala" rel="noopener noreferrer"&gt;&lt;code&gt;ModelMapperK[Id, S &amp;lt;: Scope, A, B]&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If there isn't the required &lt;code&gt;ScopeContext&lt;/code&gt; instance in the class | object scope the compilation fails.&lt;/p&gt;

&lt;p&gt;Since there can't be more than one implicit instance for type in the scala scope (class, object, etc...) the compilation fails in the case of multiple &lt;code&gt;ScopeContext&lt;/code&gt; defined. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Definition&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;

&lt;span class="c1"&gt;//persistence&lt;/span&gt;
&lt;span class="k"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;UserEntity&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;    
    &lt;span class="k"&gt;implicit&lt;/span&gt; &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;userEntityToDomain&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ModelMapper&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Scope.Persistence&lt;/span&gt;, &lt;span class="kt"&gt;UserEntity&lt;/span&gt;, &lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt;
      &lt;span class="nv"&gt;ModelMapper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;scoped&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Scope.Persistence&lt;/span&gt;&lt;span class="o"&gt;](&lt;/span&gt;&lt;span class="n"&gt;userEntity&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;???)&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;//endpoint&lt;/span&gt;
&lt;span class="k"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;UserContract&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;    
    &lt;span class="k"&gt;implicit&lt;/span&gt; &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;userToUserContract&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ModelMapper&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Scope.Endpoint&lt;/span&gt;, &lt;span class="kt"&gt;User&lt;/span&gt;, &lt;span class="kt"&gt;UserContract&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt;
      &lt;span class="nv"&gt;ModelMapper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;scoped&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Scope.Endpoint&lt;/span&gt;&lt;span class="o"&gt;](&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;???)&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;

&lt;span class="c1"&gt;//persistence&lt;/span&gt;
&lt;span class="k"&gt;implicit&lt;/span&gt; &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;scopeCtx&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;TypedScopeContext&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Scope.Persistence&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; 
  &lt;span class="nv"&gt;ScopeContext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;of&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Scope.Persistence&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;userEntity&lt;/span&gt; &lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UserEntity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;???&lt;/span&gt;
&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;userEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;scoped&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;as&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;


&lt;span class="c1"&gt;//endpoint&lt;/span&gt;
&lt;span class="k"&gt;implicit&lt;/span&gt; &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;scopeCtx&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;TypedScopeContext&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Scope.Endpoint&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; 
  &lt;span class="nv"&gt;ScopeContext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;of&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Scope.Endpoint&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;???&lt;/span&gt;
&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;userContract&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UserContract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;scoped&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;as&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;UserContract&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you don't want to explicitly declare the implicit variable for the scope you can simply extend the trait &lt;a href="https://github.com/geirolz/scope/blob/main/core/src/main/scala/scope/InScope.scala" rel="noopener noreferrer"&gt;&lt;code&gt;InScope&lt;/code&gt;&lt;/a&gt; passing the scope type &lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="c1"&gt;//persistence&lt;/span&gt;&lt;br&gt;
&lt;span class="k"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;MyPersistence&lt;/span&gt; &lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;InScope&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Scope.Persistence&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br&gt;
  &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;userEntity&lt;/span&gt; &lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UserEntity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;???&lt;/span&gt;&lt;br&gt;
  &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;userEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;scoped&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;as&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;br&gt;
&lt;span class="o"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="c1"&gt;//endpoint&lt;/span&gt;&lt;br&gt;
&lt;span class="k"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;MyEndpoint&lt;/span&gt; &lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;InScope&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Scope.Endpoint&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br&gt;
  &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;???&lt;/span&gt;&lt;br&gt;
  &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;userContract&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UserContract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;scoped&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;as&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;UserContract&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;br&gt;
&lt;span class="o"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Advantages&lt;br&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Composability, even with effects is simpler &lt;/li&gt;
&lt;li&gt;Compile-time check that the users are using the mappers in the right scope&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Problems
&lt;/h4&gt;

&lt;p&gt;No guarantee that the user correctly maps the scope, this reduces the problems. The scopes are less than mappers &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Scope&lt;/code&gt; doesn't totally resolve the problem, but for sure can help offering one more tool to have a clean and structured code.&lt;/p&gt;

</description>
      <category>scala</category>
      <category>functional</category>
      <category>design</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Database migrations in Scala</title>
      <dc:creator>David Geirola</dc:creator>
      <pubDate>Tue, 02 Nov 2021 08:12:19 +0000</pubDate>
      <link>https://dev.to/geirolz/database-migrations-in-scala-2lcl</link>
      <guid>https://dev.to/geirolz/database-migrations-in-scala-2lcl</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/geirolz/fly4s"&gt;https://github.com/geirolz/fly4s&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The most famous library to handle database migrations in Java is for sure Flyway. &lt;br&gt;
It works very well and the community edition has a lot of features as well.&lt;/p&gt;
&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;Flyway APIs are written in the standard OOP paradigm, so throwing exceptions, manually managing resources, etc...&lt;/p&gt;
&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Fly4s&lt;/code&gt; is a lightweight, simple and functional wrapper for Flyway.&lt;br&gt;
The aim of &lt;code&gt;Fly4s&lt;/code&gt; is straightforward, wrapping the &lt;code&gt;Flyway&lt;/code&gt; APIs in order to guarantee referential transparency, pureness, resource handling and type safety. To achieve this goal, &lt;code&gt;Fly4s&lt;/code&gt; use the typelevel libraries &lt;code&gt;cats&lt;/code&gt; and &lt;code&gt;cats-effect&lt;/code&gt;. &lt;/p&gt;
&lt;h3&gt;
  
  
  Getting started
&lt;/h3&gt;

&lt;p&gt;The first step, import the &lt;code&gt;Fly4s&lt;/code&gt; library in our SBT project.&lt;br&gt;
So, add the dependency in your &lt;code&gt;build.sbt&lt;/code&gt; file. &lt;br&gt;
Fly4s depends on Flyway, so we'll have access to Flyway as well&lt;/p&gt;

&lt;p&gt;(check the GitHub repo for the latest version)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;libraryDependencies += "com.github.geirolz" %% "fly4s-core" % "0.0.4"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Migrations files
&lt;/h3&gt;

&lt;p&gt;As the plain Flyway, we have to create a folder that will contain our migrations scripts, often in &lt;code&gt;resources/db&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In this folder, we have to put all our migration. We can have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://flywaydb.org/documentation/tutorials/baselineMigrations"&gt;Baseline migrations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://flywaydb.org/documentation/tutorials/repeatable"&gt;Repeatable migrations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://flywaydb.org/documentation/tutorials/undo"&gt;Undo migrations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this example, we are going to use a simple &lt;code&gt;baseline migration&lt;/code&gt; to add a table to our database schema.&lt;/p&gt;

&lt;p&gt;Baseline migrations are versioned and executed only when needed. The version is retrieved from the script file name.&lt;/p&gt;

&lt;p&gt;So in this case, &lt;code&gt;V001__create_user_table.sql&lt;/code&gt;, the version will be &lt;code&gt;001&lt;/code&gt;(remember the double underscore after &lt;code&gt;V&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Here we have our first migration(for MySQL database)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;resources/db/V001__create_user_table.sql&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="nc"&gt;CREATE&lt;/span&gt; &lt;span class="nc"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;`user`&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;`id`&lt;/span&gt; &lt;span class="nf"&gt;bigint&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;NOT&lt;/span&gt; &lt;span class="nc"&gt;NULL&lt;/span&gt; &lt;span class="nc"&gt;AUTO_INCREMENT&lt;/span&gt; &lt;span class="nc"&gt;PRIMARY&lt;/span&gt; &lt;span class="nc"&gt;KEY&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;`name`&lt;/span&gt; &lt;span class="nf"&gt;varchar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;NOT&lt;/span&gt; &lt;span class="nc"&gt;NULL&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;`surname`&lt;/span&gt; &lt;span class="nf"&gt;varchar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;NOT&lt;/span&gt; &lt;span class="nc"&gt;NULL&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Defining database configuration (optional)
&lt;/h3&gt;

&lt;p&gt;A good practice is to create a case class to handle the database configuration(this combined with PureConfig or other config libraries makes your app very robust from the configuration point of view)&lt;/p&gt;

&lt;p&gt;Let's create a simple case class to achieve this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DatabaseConfig&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;],&lt;/span&gt;
  &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Char&lt;/span&gt;&lt;span class="o"&gt;]],&lt;/span&gt;
  &lt;span class="n"&gt;migrationsTable&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;migrationsLocations&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;N.B. apart from the common fields such &lt;code&gt;url&lt;/code&gt;, &lt;code&gt;user&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt; we'll use: &lt;code&gt;migrationsTable&lt;/code&gt; to define the Flyway table name(used to store the migration status) and &lt;code&gt;migrationsLocations&lt;/code&gt; to specify a list of the folders that contain our migration scripts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Instantiating Fly4s
&lt;/h3&gt;

&lt;p&gt;Ok so, now we have all our migration scripts in our folder(&lt;code&gt;resources/db&lt;/code&gt;), we have &lt;code&gt;Fly4s&lt;/code&gt; as a dependency of our project, and we have a case class that will contain the database configuration.&lt;/p&gt;

&lt;p&gt;To instantiate &lt;code&gt;Fly4s&lt;/code&gt; we can use &lt;code&gt;make&lt;/code&gt; to create a new DataSource(under the hood) starting from the parameters or &lt;code&gt;makeFor&lt;/code&gt; in order to create it for an already existent &lt;code&gt;DataSource&lt;/code&gt;(for example from Doobie HikariDataSource).&lt;br&gt;
&lt;code&gt;make&lt;/code&gt; and &lt;code&gt;makeFor&lt;/code&gt; method returns a &lt;a href="https://typelevel.org/cats-effect/docs/std/resource"&gt;&lt;code&gt;Resource&lt;/code&gt;&lt;/a&gt; type class that when released/interrupted safely close the &lt;code&gt;DataSource&lt;/code&gt; connection.&lt;/p&gt;

&lt;p&gt;In both &lt;code&gt;make&lt;/code&gt; and &lt;code&gt;makeFor&lt;/code&gt; methods, we can specify the parameter &lt;code&gt;config&lt;/code&gt;. &lt;code&gt;Fly4sConfig&lt;/code&gt; is a trivial wrapper for flyway &lt;code&gt;Configuration&lt;/code&gt; but instead of having a builder, we have a case class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;dbConfig&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;DatabaseConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;???&lt;/span&gt;
&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;fly4sRes&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Resource&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;IO&lt;/span&gt;, &lt;span class="kt"&gt;Fly4s&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;Fly4s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;make&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;](&lt;/span&gt;
  &lt;span class="n"&gt;url&lt;/span&gt;                 &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;dbConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;url&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;user&lt;/span&gt;                &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;dbConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;user&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;password&lt;/span&gt;            &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;dbConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;password&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Fly4sConfig&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;table&lt;/span&gt;     &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;dbConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;migrationsTable&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;locations&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;Location&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;dbConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;migrationsLocations&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using Fly4s
&lt;/h3&gt;

&lt;p&gt;Ok, we have done with the configuration!&lt;br&gt;
We are ready to migrate our database schema with the power of Flyway and the safety of Functional Programming!&lt;/p&gt;

&lt;p&gt;We can use &lt;code&gt;use&lt;/code&gt; or &lt;code&gt;evalMap&lt;/code&gt; from &lt;code&gt;Resource&lt;/code&gt; to safely access to the Fly4s instance. In case we have multiple &lt;code&gt;Resource&lt;/code&gt;s in our application probably &lt;code&gt;evalMap&lt;/code&gt; allow us to better combine them using and release them all together at the same time.&lt;/p&gt;

&lt;p&gt;We can create a simple utility method to do this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;migrateDb&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;dbConfig&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;DatabaseConfig&lt;/span&gt;
  &lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Resource&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;IO&lt;/span&gt;, &lt;span class="kt"&gt;Unit&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt;
    &lt;span class="nv"&gt;Fly4s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;make&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;](&lt;/span&gt;
      &lt;span class="n"&gt;url&lt;/span&gt;                 &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;dbConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;url&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;user&lt;/span&gt;                &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;dbConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;user&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;password&lt;/span&gt;            &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;dbConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;password&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Fly4sConfig&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;table&lt;/span&gt;     &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;dbConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;migrationsTable&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;locations&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;Location&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;dbConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;migrationsLocations&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="py"&gt;evalMap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fly4s&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;_&lt;/span&gt;               &lt;span class="k"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="nv"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;debug&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="s"&gt;"Applying migration for ${dbConfig.name}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;migrationResult&lt;/span&gt; &lt;span class="k"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="nv"&gt;fly4s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;validateAndMigrate&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="py"&gt;result&lt;/span&gt;
          &lt;span class="k"&gt;_&lt;/span&gt; &lt;span class="k"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="nv"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="s"&gt;" Applied ${migrationResult.migrationsExecuted} migrations to ${dbConfig.name} database"&lt;/span&gt;
          &lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nf"&gt;yield&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt;
      &lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusions
&lt;/h3&gt;

&lt;p&gt;We have done it! So, to recap, we have:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Created a folder under &lt;code&gt;resources&lt;/code&gt; to put our migrations(&lt;code&gt;db&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Imported &lt;code&gt;Fly4s&lt;/code&gt; as a dependency in our project&lt;/li&gt;
&lt;li&gt;Created a configuration case class to describe our database configuration&lt;/li&gt;
&lt;li&gt;Instantiated a &lt;code&gt;Fly4s&lt;/code&gt; instance creating a new &lt;code&gt;DataSource&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Migrated our database using &lt;code&gt;validateAndMigrate&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;At the application shutdown/interruption &lt;code&gt;Resource&lt;/code&gt;(from cats-effect) will safely release the &lt;code&gt;DataSource&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With a few lines, we have migrated our database safely handling the connection and the configuration.&lt;/p&gt;

&lt;p&gt;As flyway, Fly4s provides multiple methods such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;validateAndMigrate&lt;/li&gt;
&lt;li&gt;migrate&lt;/li&gt;
&lt;li&gt;undo&lt;/li&gt;
&lt;li&gt;validate&lt;/li&gt;
&lt;li&gt;clean&lt;/li&gt;
&lt;li&gt;info&lt;/li&gt;
&lt;li&gt;baseline&lt;/li&gt;
&lt;li&gt;repair&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Useful links
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://github.com/geirolz/fly4s"&gt;https://github.com/geirolz/fly4s&lt;/a&gt;&lt;br&gt;
&lt;a href="https://flywaydb.org/documentation"&gt;https://flywaydb.org/documentation&lt;/a&gt;&lt;br&gt;
&lt;a href="https://typelevel.org/cats/"&gt;https://typelevel.org/cats/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://typelevel.org/cats-effect/"&gt;https://typelevel.org/cats-effect/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://pureconfig.github.io/"&gt;https://pureconfig.github.io/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>scala</category>
      <category>database</category>
      <category>functional</category>
      <category>typesafe</category>
    </item>
    <item>
      <title>"Type Disjunctions" in Scala</title>
      <dc:creator>David Geirola</dc:creator>
      <pubDate>Wed, 06 Nov 2019 15:37:35 +0000</pubDate>
      <link>https://dev.to/geirolz/type-disjunctions-in-scala-4mlb</link>
      <guid>https://dev.to/geirolz/type-disjunctions-in-scala-4mlb</guid>
      <description>&lt;p&gt;Hi guys,&lt;/p&gt;

&lt;p&gt;Today i'd like to talk about &lt;strong&gt;Type Disjunctions&lt;/strong&gt; (Union Type) in Scala.&lt;/p&gt;

&lt;p&gt;As we all know this feature is &lt;em&gt;not available&lt;/em&gt; in Scala yet but i'd like to share with you my solution about a case i've had this week working on my library.&lt;/p&gt;

&lt;p&gt;I'm writing a FP library to edit and work easily with XML in Scala, it's based on standard &lt;em&gt;scala-xml&lt;/em&gt; library and &lt;em&gt;Cats&lt;/em&gt;. You can check this library on github at:  &lt;a href="https://github.com/geirolz/advxml"&gt;https://github.com/geirolz/advxml&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Case
&lt;/h1&gt;

&lt;p&gt;I've defined a new type alias named &lt;em&gt;ValidatedEx&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;ValidatedEx&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;+T&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ValidatedNel&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Throwable&lt;/span&gt;, &lt;span class="kt"&gt;T&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// = Validated[NonEmptyList[E], A]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I wanted to add new methods on this type using extension methods, one of these was a method named "transform" with the aim to convert  &lt;em&gt;ValidatedEx&lt;/em&gt; instance into &lt;em&gt;F[_]&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Must have:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One single method, the user should not have the burden to choose the right method depending on the case.&lt;/li&gt;
&lt;li&gt;Use Cats instances, i don't want to reinventing the wheel.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  First solution [Failed]
&lt;/h1&gt;

&lt;p&gt;Using an implicit monad error in order to convert &lt;em&gt;ValidatedEx&lt;/em&gt; to &lt;em&gt;F[_]&lt;/em&gt;, pattern matching over the instance, invoking &lt;em&gt;pure&lt;/em&gt; or &lt;em&gt;raiseError&lt;/em&gt; depending on the case and the game is done!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;    &lt;span class="k"&gt;implicit&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ValidatedExOps&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;A&lt;/span&gt;&lt;span class="o"&gt;](&lt;/span&gt;&lt;span class="n"&gt;validated&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ValidatedEx&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;A&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;transform&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;F&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="k"&gt;_&lt;/span&gt;&lt;span class="o"&gt;]](&lt;/span&gt;&lt;span class="k"&gt;implicit&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;MonadError&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;F&lt;/span&gt;, &lt;span class="kt"&gt;NonEmptyList&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Throwable&lt;/span&gt;&lt;span class="o"&gt;]])&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;F&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;A&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt;
          &lt;span class="n"&gt;validated&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Valid&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;   &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;F&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;pure&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Invalid&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;F&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;raiseError&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
          &lt;span class="o"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yea! It works! But...i can't use standard monads error provided by cats...&lt;/p&gt;

&lt;p&gt;This wont compile because in the scope is not present an implicit instance of &lt;em&gt;MonadError[Try, NonEmptyList[Throwable]]&lt;/em&gt; and cats provides only &lt;em&gt;MonadError[Try, Throwable].&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;      &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;cats.instances.try_._&lt;/span&gt;
      &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ValidatedEx&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Valid&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TEST"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;//No implicit found for parameter F:MonadError[Try, NonEmptyList[Throwable]] &lt;/span&gt;
      &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;tryValue&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Try&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;transform&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Try&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I don't want to create a new monad error for each type, my library must work with cats!&lt;/p&gt;

&lt;h1&gt;
  
  
  Second solution [Failed]
&lt;/h1&gt;

&lt;p&gt;Using &lt;em&gt;natural transformation!&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;      &lt;span class="k"&gt;implicit&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ValidatedExOps&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;A&lt;/span&gt;&lt;span class="o"&gt;](&lt;/span&gt;&lt;span class="n"&gt;validated&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ValidatedEx&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;A&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;transform&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;F&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="k"&gt;_&lt;/span&gt;&lt;span class="o"&gt;]](&lt;/span&gt;&lt;span class="k"&gt;implicit&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ValidatedEx&lt;/span&gt; &lt;span class="kt"&gt;~&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;F&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;F&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;A&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;F&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validated&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;

      &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;cats.instances.try_._&lt;/span&gt;
      &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ValidatedEx&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Valid&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TEST"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;//No implicit found for parameter F:ValidatedEx ~&amp;gt; F&lt;/span&gt;
      &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;tryValue&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Try&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;transform&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Try&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we go again, this solution require ad-hoc implementations of &lt;em&gt;FunctionK&lt;/em&gt; for each type and i don't want to reinventing the wheel.&lt;/p&gt;

&lt;h1&gt;
  
  
  Third solution [Success]
&lt;/h1&gt;

&lt;p&gt;I want have just one method, keep all possibilities open and substantially have two MonadError in the signature but only one is required. This smell like an union type!&lt;/p&gt;

&lt;p&gt;Let's define "union types" using Either with a very easy solution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;      &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;\/&lt;/span&gt;&lt;span class="err"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;+A&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="err"&gt;]&lt;/span&gt;           &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Either&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;A&lt;/span&gt;, &lt;span class="kt"&gt;B&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
      &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;MonadEx&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;F&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="k"&gt;_&lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;        &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MonadError&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;F&lt;/span&gt;, &lt;span class="kt"&gt;Throwable&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
      &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;MonadNelEx&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;F&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="k"&gt;_&lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;     &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MonadError&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;F&lt;/span&gt;, &lt;span class="kt"&gt;NonEmptyList&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Throwable&lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;

      &lt;span class="k"&gt;implicit&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ValidatedExOps&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;A&lt;/span&gt;&lt;span class="o"&gt;](&lt;/span&gt;&lt;span class="n"&gt;validated&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ValidatedEx&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;A&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;transform&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;F&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="k"&gt;_&lt;/span&gt;&lt;span class="o"&gt;]](&lt;/span&gt;&lt;span class="k"&gt;implicit&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;MonadEx&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;F&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;\/&lt;/span&gt; &lt;span class="nc"&gt;MonadNelEx&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;F&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;F&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;A&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt;
          &lt;span class="n"&gt;F&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Left&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt;
              &lt;span class="n"&gt;validated&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Valid&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;pure&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="c1"&gt;//AggregatedException is a my own class that just collapse multiple exceptions into one &lt;/span&gt;
                &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Invalid&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exs&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;raiseError&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AggregatedException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;exs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
              &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Right&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt;
              &lt;span class="n"&gt;validated&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Valid&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;pure&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Invalid&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exs&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;raiseError&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exs&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
              &lt;span class="o"&gt;}&lt;/span&gt;
          &lt;span class="o"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But...still fail, obviously there isn't an implicit instance for &lt;em&gt;Either[MonadEx[F], MonadNelEx[F]]&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;      &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;cats.instances.try_._&lt;/span&gt;
      &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ValidatedEx&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Valid&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TEST"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;//No implicit found for parameter F:Either[MonadEx[F], MonadNelEx[F]]&lt;/span&gt;
      &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;tryValue&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Try&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;transform&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Try&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's wrap what cats provides, let's "intercept" monads error provided in the scope and wrap them into Either.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;      &lt;span class="k"&gt;implicit&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;monadExLeftDsj&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;F&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="k"&gt;_&lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;
        &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;implicit&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;MonadEx&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;F&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;MonadEx&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;F&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;\/&lt;/span&gt; &lt;span class="nc"&gt;MonadNelEx&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;F&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Left&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;implicit&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;monadNelExRightDsj&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;F&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="k"&gt;_&lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;
        &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;implicit&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;MonadNelEx&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;F&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;MonadEx&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;F&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;\/&lt;/span&gt; &lt;span class="nc"&gt;MonadNelEx&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;F&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Right&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And for a more generic solution we can write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;      &lt;span class="c1"&gt;//for explicit values&lt;/span&gt;
      &lt;span class="k"&gt;implicit&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;aLeftDsj&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;A&lt;/span&gt;&lt;span class="o"&gt;](&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;A&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;A&lt;/span&gt; &lt;span class="kt"&gt;\/&lt;/span&gt; &lt;span class="kt"&gt;*&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Left&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;implicit&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;bRightDsj&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;B&lt;/span&gt;&lt;span class="o"&gt;](&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;B&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;*&lt;/span&gt; &lt;span class="kt"&gt;\/&lt;/span&gt; &lt;span class="kt"&gt;B&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Right&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

      &lt;span class="c1"&gt;//for implicit values&lt;/span&gt;
      &lt;span class="k"&gt;implicit&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;aLeftDsj&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;A&lt;/span&gt;&lt;span class="o"&gt;](&lt;/span&gt;&lt;span class="k"&gt;implicit&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;A&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;A&lt;/span&gt; &lt;span class="kt"&gt;\/&lt;/span&gt; &lt;span class="kt"&gt;*&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Left&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;implicit&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;bRightDsj&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;B&lt;/span&gt;&lt;span class="o"&gt;](&lt;/span&gt;&lt;span class="k"&gt;implicit&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;B&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;*&lt;/span&gt; &lt;span class="kt"&gt;\/&lt;/span&gt; &lt;span class="kt"&gt;B&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Right&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Done! It works!&lt;/p&gt;

&lt;p&gt;I know that this solution isn't perfect and beautiful, i hate implicit conversions, and i also know that union types are coming but in the meantime this is a simple solution to partially bypass this scala loss for a specific case like mine.&lt;/p&gt;

&lt;p&gt;Tell me what do you think about this solution :)&lt;/p&gt;

</description>
      <category>scala</category>
      <category>functional</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Edit XML in Scala in a FP way</title>
      <dc:creator>David Geirola</dc:creator>
      <pubDate>Wed, 14 Aug 2019 18:51:27 +0000</pubDate>
      <link>https://dev.to/geirolz/edit-xml-in-scala-21mg</link>
      <guid>https://dev.to/geirolz/edit-xml-in-scala-21mg</guid>
      <description>&lt;p&gt;Hi guys , i'm new here and this in my first post!&lt;/p&gt;

&lt;p&gt;I'm here because i'd like to share with you a small project i realized for my company due the difficulties and boilerplates found using Scala XML library's API.&lt;/p&gt;

&lt;p&gt;I hope that someone can contribute to it.&lt;/p&gt;

&lt;p&gt;Github: &lt;a href="https://github.com/geirolz/advxml"&gt;https://github.com/geirolz/advxml&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Append, Remove, Replace XML nodes&lt;/li&gt;
&lt;li&gt;Edit node's attributes&lt;/li&gt;
&lt;li&gt;Read XML handling optionality and mandatory nodes and attributes&lt;/li&gt;
&lt;li&gt;Convert XML into Object and viceversa&lt;/li&gt;
&lt;li&gt;Normalize XML&lt;/li&gt;
&lt;li&gt;Convert Java Document to Scala NodeSeq&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.github.geirolz.advxml.all._&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;scala.xml._&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;scala.util._&lt;/span&gt;


&lt;span class="c1"&gt;//import MonadError instance for Try&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;cats.instances.try_._&lt;/span&gt;

&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;doc&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Elem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Persons&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="nc"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Mimmo"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Cars&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="nc"&gt;Brand&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Fiat"&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Cars&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Persons&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;


&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;rule&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;_&lt;/span&gt; &lt;span class="o"&gt;\&lt;/span&gt; &lt;span class="s"&gt;"Person"&lt;/span&gt; &lt;span class="o"&gt;\&lt;/span&gt; &lt;span class="s"&gt;"Cars"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
 &lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Append&lt;/span&gt;&lt;span class="o"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="nc"&gt;Brand&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Lamborghini"&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;)&lt;/span&gt;
 &lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Append&lt;/span&gt;&lt;span class="o"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="nc"&gt;Brand&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Ferrari"&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;)&lt;/span&gt;
 &lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Append&lt;/span&gt;&lt;span class="o"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="nc"&gt;Brand&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Bmw"&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;)&lt;/span&gt;


&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Try&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;NodeSeq&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;transform&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Try&lt;/span&gt;&lt;span class="o"&gt;](&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope this small project can help someone in desperation with Scala XML library&lt;/p&gt;

&lt;p&gt;Let me know what you think about it :)&lt;/p&gt;

</description>
      <category>scala</category>
      <category>xml</category>
    </item>
  </channel>
</rss>
