Counter with increment and decrement buttons
Preface: I haven't worked in the Android ecosystem, so this review is mostly looking at the Kotlin side of things. I've also had minimal exposure to the Redux pattern.



Some low hanging fruit that IntelliJ IDEA points out:


return state is unreachable code in fun reducer. Control flow will always exit as action can only be .INCREMENT or .DECREMENT. I would use an else -&gt; throw IllegalStateException("Invalid Action") in the when, to keep safety in the case of expanding the enum class Action in the future. As a bonus, this is not marked as unreachable code, as IntelliJ recognizes it as a fallback case.
Explicit type arguments in val store = Store&lt;Action, State&gt;... are not required: just val store = Store(State(), ::reducer) works fine and Kotlin infers the types. This is Kotlin's biggest advantage over Java.
class Store&lt;Action, State&gt; can have declaration site variance. Read the link for information about what this means; it is written class Store&lt;in Action, out State&gt; and does not change any semantics of the present code.
private val reducer can be declared directly in the constructor. It's personal preference whether you declare it there or not, but if you do, I would probably also declare currentState there as well (instead of initialState).


Some other points:


I wouldn't use the package com.myapplication; it's a placeholder. Instead, give it something that identifies this package as yours. Oracle's Java tutorial recommends using a domain you own. Even though I do own http://cad97.com, rather than use package com.cad97.project I usually use just cad97.project, as a holdover from before I bought the domain. For you, this pattern would suggest a base package of daniel_t. If you do not own the domain, DO NOT use a com (or any other common TLD) base package.
Personally, I typically don't specify argument labels on function types. (This refers to the types for parameters to the Store constructor, the MutableMap types, the subscribe method.)
Java (and in my adventures so far, Kotlin) typically uses one-letter types for generic types, to distinguish them from regular types. This is compounded by the fact that your generic Action is named the same as your concrete Action. How you resolve this is up to the programmer, but in an ideal world you would not have this conflict of names.
You can return dispose directly: just write return { subscribers.remove(id) }
Store::notifySubscribers can be written as a single-expression function: private fun notifySubscribers() = subscribers.values.forEach { it(currentState) }
subscribers can be declared as private var subscribers = mutableMapOf&lt;Int, (State) -&gt; Unit&gt;()
Rather than return Error from Store::dispatch, use IllegalStateException, as it is more descriptive of the reason for the error.
By the format of Store::dispatch, it looks like what you're trying to do is use a Lock. Kotlin provides special support for this, which would be written something like this:




private val dispatchLock = ReentrantLock() // replaces dispatching

fun dispatch(action: Action) = dispatchLock.withLock {
    currentState = reducer(action, currentState)
    notifySubscribers()
}