## Ior

`Ior` represents an inclusive-or relationship between two data types. This makes it very similar to the `Either` data type, which represents an “exclusive-or” relationship. An `Ior<A, B>` (also written as `A Ior B`) can contain either an `A`, a `B`, or both. Another similarity to `Either` is that `Ior` is right-biased, which means that the `map` and `flatMap` functions will work on the right side of the `Ior`, in our case the `B` value. You can see this in the function signature of `map`:

``````fun <D> map(f: (B) -> D): Ior<A, D>
``````

We can create `Ior` values using `Ior.Left`, `Ior.Right` and `Ior.Both`:

``````import arrow.*
import arrow.data.*

Ior.Right(42)
// Right(value=42)
``````
``````Ior.Left("Error")
// Left(value=Error)
``````
``````Ior.Both("Warning", 41)
// Both(leftValue=Warning, rightValue=41)
``````

Arrow also offers extension functions for `Ior`, the `leftIor`, `rightIor` and `bothIor`:

``````3.rightIor()
// Right(value=3)
``````
``````"Error".leftIor()
// Left(value=Error)
``````
``````("Warning" to 3).bothIor()
// Both(leftValue=Warning, rightValue=3)
``````

When we look at the `Monad` or `Applicative` instances of `Ior`, we can see that they actually require a `Semigroup` instance on the left side. This is because `Ior` will actually accumulate failures on the left side, very similarly to how the `Validated` data type does. This means we can accumulate data on the left side while also being able to short-circuit upon the first right-side-only value. For example, we might want to accumulate warnings together with a valid result and only halt the computation on a “hard error” Here’s an example of how we are able to do that:

``````data class User(val name: String, val pw: String)

}

}

fun validateUser(name: String, pass: String) =
}.fix()
``````

Now we’re able to validate user data and also accumulate non-fatal warnings:

``````validateUser("John", "password12")
``````
``````validateUser("john.doe", "password")
``````
``````validateUser("jane", "short")
``````

To extract the values, we can use the `fold` method, which expects a function for each case the `Ior` can represent:

``````validateUser("john.doe", "password").fold(
{ "Success \$it" },
{ warnings, (name) -> "Warning: \$name; The following warnings occurred: \${warnings.show()}" }
)
//Warning: john.doe; The following warnings occurred: Dot in name is deprecated, Password should be longer
``````

Similar to Validated, there is also a type alias for using a `NonEmptyList` on the left side.

``````typealias IorNel<A, B> = Ior<Nel<A>, B>
``````
``````Ior.leftNel<String, Int>("Error")
// Left(value=NonEmptyList(all=[Error]))
``````
``````Ior.bothNel("Warning", 41)
// Both(leftValue=NonEmptyList(all=[Warning]), rightValue=41)
``````

We can also convert our `Ior` to `Either`, `Validated` or `Option`. All of these conversions will discard the left side value if both are available:

``````Ior.Both("Warning", 41).toEither()
// Right(b=41)
``````
``````Ior.Both("Warning", 41).toValidated()
// Valid(a=41)
``````
``````Ior.Both("Warning", 41).toOption()
// Some(41)
``````

## Credits

Contents partially adapted from Cats Ior