https://github.com/albertllousas/state-monad-with-kotlin
https://github.com/albertllousas/state-monad-with-kotlin
Last synced: about 2 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/albertllousas/state-monad-with-kotlin
- Owner: albertllousas
- Created: 2023-07-11T05:13:11.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2023-07-11T05:18:46.000Z (almost 2 years ago)
- Last Synced: 2025-01-30T22:48:25.768Z (3 months ago)
- Language: Kotlin
- Size: 63.5 KB
- Stars: 1
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: readme.md
Awesome Lists containing this project
README
# State monad with kotlin
## Description
Have you heard about the state monad? This repo implements this functional programming pattern using kotlin and explains
the basics of it.## Example using state monad
- [Rock paper scissors game](https://en.wikipedia.org/wiki/Rock_paper_scissors)
- [Code](src/main/kotlin/example/RockPaperScissors.kt)
- [Tests & usage](src/test/kotlin/example/RockPaperScissorsTest.kt)
- [State monad](src/main/kotlin/statemonad/State.kt)## Stateful computations
A stateful computation is a function that takes some state and returns a value along with a new state:
`state -> tuple(newState, result)`
Example in kotlin, a function that checks if a number is even and keeps track of all evens already checked:
```kotlin
fn isEven(num: Int, totalOfEvens: Int): Pair =
if (num % 2 == 0) Pair(true, totalOfEvens.inc) else Pair(false, totalOfEvens)
```What if we abstract the previous function in something more generic?
Let's wrap our initial function in a new type:
```shell
state -> (state, result) to State(f: state -> (state, result))
```In kotlin:
```kotlin
data class State(val run: (STATE) -> Pair)
```And let's refactor our previous code:
```kotlin
fun isEven(num: Int): State = State { state ->
if (num % 2 == 0) Pair(true, state.inc) else Pair(false, state)
}
```Simple, state monad is just a **datatype wrapping a stateful computation**
# Wrapping up
We can not finish without mentioning that state is a monad, therefore it should implement `map` and `flatmap` functions.
In this example it would be missing to implement `get` and `put` functions that usually come alongside the pattern as well.