A Moore machine is a comonadic data structure which holds a state and in order to change it we need to dispatch events of some specific type. This approach is similar to the Elm architecture or Redux.

For creating a Moore machine we need its initial state and a handle function which will determine the inputs it can accept and how the state will change with each one.

import arrow.core.*

fun handleRoute(route: String): Moore<String, Id<String>> = when (route) {
  "About" -> Moore(Id("About"), ::handleRoute)
  "Home" -> Moore(Id("Home"), ::handleRoute)
  else -> Moore(Id("???"), ::handleRoute)

val routerMoore = Moore(Id("???"), ::handleRoute)

// About

We also have an extract function which returns the current state and a coflatMap which transforms its type:

    .coflatMap { (view) ->
      when (view.extract()) {
        "About" -> 1
        "Home" -> 2
        else -> 0
// 0

Supported type classes

Module Type classes
arrow.typeclasses Comonad, Functor