marc0der
06/20/2020, 10:58 AMmarc0der
06/20/2020, 10:59 AMState<S, A>
. We can get around this in the short term by specifying a monad instance that is tied to s specific implementation, in other words declare an `IntState<A>`:marc0der
06/20/2020, 11:00 AMval intStateMonad = object : Monad<ForIntState> {
override fun <A> unit(a: A): IntStateOf<A> =
IntState { s: Int -> Pair(a, s) }
override fun <A, B> flatMap(
fa: IntStateOf<A>,
f: (A) -> IntStateOf<B>
): IntStateOf<B> =
fa.fix().flatMap { a: A -> f(a).fix() }
}
marc0der
06/20/2020, 11:02 AMState<S, A>
needs to extend from IntStateOf<A>
. Fine, but when we introduce a new member to the state monad family, say doubleStateMonad
, we are now constrained in that State<S, A>
cannot also extend from DoubleStateOf<A>
as well! Even if we could, having to keep extending our base data type doesn't scale very well.marc0der
06/20/2020, 11:02 AMmarc0der
06/20/2020, 11:03 AMdef stateMonad[S] = new Monad[({type f[x] = State[S,x]})#f] {
def unit[A](a: => A): State[S,A] = State(s => (a, s))
def flatMap[A,B](st: State[S,A])(f: A => State[S,B]): State[S,B] =
st flatMap f
}
marc0der
06/20/2020, 11:04 AMraulraja
06/20/2020, 11:40 AMraulraja
06/20/2020, 11:42 AMmarc0der
06/20/2020, 11:42 AMraulraja
06/20/2020, 11:43 AMraulraja
06/20/2020, 11:44 AMmarc0der
06/20/2020, 11:46 AMstateMonad[S]
. I realise that we won't have something like the type lambdas available, but any help here with a workaround would be super appreciated.simon.vergauwen
06/20/2020, 12:42 PM({type f[x] = State[S,x]})#f
this loosely translates to an anonymous function at the typelevel which creates a type for State
which partially applies S
.
If we say that Kind<F, A> == F[A]
, Kind2<F, A, B> == F[A, B]
and so on. We can say that Kind
is constructor at the typelevel, which takes F
and applies A
to it.
The trick however is that `Kind2<F, A, B> == Kind<Kind<F, A>, B>
. So you can partially apply type arguments.
In you case you want to apply S
to ForState
.
So ({type f[x] = State[S,x]})#f
is the equivalent of:
typealias StatePartialOf<S> = Kind<ForState, S>
Where A
can be applied by doing Kind<StatePartialOf<S>, A>
== Kind2<ForState, S, A>
== State<S, A>
.simon.vergauwen
06/20/2020, 12:48 PMS
to StatePartialOf<S>
, and apply A
in map
.
interface StateMonad<S> : Monad<StatePartialOf<S>> {
fun <A, B> Kind<StatePartialOf<S>, A>.map(f: (A) -> B): Kind<StatePartialOf<S>, B>
}
simon.vergauwen
06/20/2020, 12:50 PMStateTOf
is an alias for Kind3<ForState, F, S, A>
.
HKT boilerplate:
https://github.com/arrow-kt/arrow-fx/blob/master/arrow-fx/src/main/kotlin/arrow/fx/IO.kt#L64simon.vergauwen
06/20/2020, 12:50 PMsimon.vergauwen
06/20/2020, 12:54 PMReader/Kleisli
with extension functions.
https://gist.github.com/nomisRev/1f91710ebec1709d4ce8059812482624
Or combining suspend
with Either
https://github.com/arrow-kt/arrow-fx/tree/master/arrow-fx-coroutines#suspend----eithere-amarc0der
06/20/2020, 5:46 PMmarc0der
06/20/2020, 5:49 PMsimon.vergauwen
06/20/2020, 5:50 PMmarc0der
06/21/2020, 10:26 AMsimon.vergauwen
06/21/2020, 10:26 AM