Created
April 17, 2020 20:06
-
-
Save raulraja/e36fc68e8cf7b044b82f1eae2a23a4c6 to your computer and use it in GitHub Desktop.
Kinds without uncheched casts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** kind, all nested F's have to be also kinds `*` **/ | |
interface `*`<out F> | |
interface `*-*`<out F : `*`<F>, out A> : `*`<F> | |
interface `*-*-*`<out F : `*`<F>, out A, out B> : `*`<F> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** Bifunctor IO */ | |
class IO<out E, out A> : | |
`*`<IO<*, *>>, | |
`*-*`<IO<*, *>, A>, | |
`*-*-*`<IO<*, *>, E, A> { | |
fun <B> fmap(f: (A) -> B): IO<Nothing, B> = TODO() | |
fun <B> flatMap(f: (A) -> `*-*`<IO<*, *>, B>): IO<Nothing, B> = TODO() | |
fun <C, D> bimap(fl: (E) -> C, fr: (A) -> D): IO<C, D> = TODO() | |
companion object { | |
fun <A> just(a: A): IO<Nothing, A> = TODO() | |
} | |
} | |
// having these as member is not possible because would enforce E and A to be declared invariant | |
fun <E, A, E2 : E, AA : A> IO<E, A>.flatMapLeft2(f: (E) -> `*-*-*`<IO<*, *>, E2, AA>): IO<E2, AA> = TODO() | |
//all safe casts no need to suppress warnings | |
fun <A> `*-*`<IO<*, *>, A>.fix(): IO<*, A> = this as IO<*, A> | |
fun <E, A, EE : E, AA : A> `*-*-*`<IO<*, *>, EE, AA>.fix(): IO<EE, AA> = this as IO<EE, AA> | |
class IOMonad<L> : Monad2<IO<*, *>, L> { | |
override fun <A> just(a: A): IO<Nothing, A> = | |
IO.just(a) | |
override fun <A, B> `*-*`<IO<*, *>, A>.fmap(f: (A) -> B): IO<Nothing, B> = | |
fix().fmap(f) | |
override fun <A, B> `*-*`<IO<*, *>, A>.flatMap(f: (A) -> `*-*`<IO<*, *>, B>): IO<Nothing, B> = | |
fix().flatMap(f) | |
override fun <B, C, D> `*-*-*`<IO<*, *>, L, B>.bimap(fl: (L) -> C, fr: (B) -> D): IO<C, D> = | |
fix().bimap(fl, fr) | |
override fun <B, AA : L, BB : B> `*-*-*`<IO<*, *>, L, B>.flatMapLeft(f: (L) -> `*-*-*`<IO<*, *>, AA, BB>): IO<AA, BB> = | |
fix().flatMapLeft2(f) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** type class only accepts kinded types not just any marker **/ | |
interface Monad<F : `*`<F>> { | |
fun <A> just(a: A): `*-*`<F, A> | |
fun <A, B> `*-*`<F, A>.fmap(f: (A) -> B): `*-*`<F, B> | |
fun <A, B> `*-*`<F, A>.flatMap(f: (A) -> `*-*`<F, B>): `*-*`<F, B> | |
} | |
interface Monad2<F : `*`<F>, A> { | |
fun <B, C, D> `*-*-*`<F, A, B>.bimap(fl: (A) -> C, fr: (B) -> D): `*-*-*`<F, C, D> | |
/* lower bounds on A and B*/ | |
fun <B, AA : A, BB : B> `*-*-*`<F, A, B>.flatMapLeft(f: (A) -> `*-*-*`<F, AA, BB>): `*-*-*`<F, AA, BB> | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// this cast is now safe and not unchecked, the compiler gets it | |
// and it's an improvement over what we have | |
fun <A> `*-*`<Option<*>, A>.fix(): Option<A> = this as Option<A> | |
class Option<A> : | |
`*`<Option<*>>, | |
`*-*`<Option<*>, A> { | |
fun <B> fmap(f: (A) -> B): Option<B> = TODO() | |
fun <B> flatMap(f: (A) -> `*-*`<Option<*>, B>): Option<B> = TODO() | |
companion object { | |
fun <A> just(a: A): Option<A> = TODO() | |
} | |
} | |
object OptionMonad : Monad<Option<*>> { | |
override fun <A> just(a: A): Option<A> = | |
Option.just(a) | |
override fun <A, B> `*-*`<Option<*>, A>.fmap(f: (A) -> B): Option<B> = | |
fix().fmap(f) | |
override fun <A, B> `*-*`<Option<*>, A>.flatMap(f: (A) -> `*-*`<Option<*>, B>): Option<B> = | |
fix().flatMap(f) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment