The Decidable is a typeclass modeling contravariant decision. Decidable is the contravariant version of Alternative. Decidable basically states: Given a Kind<F, A> and a Kind<F, B> and a way to turn C into either A or B it gives you a Kind<F, C>

With decidable we can extend our serializer from the Divide/Divisible examples, by adding a decision process while serializing. Consider this example where a type is either an int or a string.

import arrow.Kind
import arrow.core.Either
import arrow.core.Tuple2
import arrow.core.identity
import arrow.core.right
import arrow.typeclasses.Decidable
import com.example.domain.*

val stringSerializer = Serializer<String> { "STRING: $it" }
val intSerializer = Serializer<Int> { "INT: $it" }

fun main(args: Array<String>) {
  val stringOrInt: Serializer<Either<String, Int>> = Serializer.decidable()
     .choose<String, Int, Either<String, Int>>(stringSerializer, intSerializer, ::identity).fix()

  val stringOrIntEither = 1.right()
  val result = stringOrInt.func(stringOrIntEither)

Main Combinators


Constructs a Kind<F, C> from a Kind<F, A>, a Kind<F, B> and a function (C) -> Either<A, B>. The intuition here is that the function “decides” what value to use by specifying it with the either constructed.

See Deriving and creating custom typeclass to provide your own Decidable instances for custom datatypes.

Data types

Module Data types Sum, EitherT, Kleisli, OptionT, StateT, WriterT
arrow.typeclasses Conested

Type Class Hierarchy