cats.data.State nos permite pasar estados adicionales como parte de un cálculo. Definimos instancias de estado que representan operaciones de estado atómico y las unimos usando map y flatMap. De esta manera, podemos modelar el estado mutable de una manera puramente funcional, sin usar la mutación real.
Reducido a su forma más simple, las instancias de State[S, A] representan funciones de tipo S => (S, A). S es el tipo del estado y A es el tipo del resultado.
import cats.data.State
val a = State[Int, String]{ state =>
(state, s"The state is $state")
}
En otras palabras, una instancia de State es una función que hace dos cosas:
• transforma un estado de entrada en un estado de salida;
• calcular un resultado.
Podemos "ejecutar" nuestra mónada desde un estado inicial. State proporciona tres métodos (run, runS y runA) que devuelven diferentes combinaciones de estado y resultado. Cada método devuelve una instancia de Eval, que State usa para mantener la seguridad de la pila. Llamamos al método de valor como de costumbre para extraer el resultado real:
// Get the state and the result:
val (state, result) = a.run(10).value
// state: Int = 10
// result: String = "The state is 10"
// Get the state, ignore the result:
val justTheState = a.runS(10).value
// justTheState: Int = 10
// Get the result, ignore the state:
val justTheResult = a.runA(10).value
// justTheResult: String = "The state is 10"