arrow-kt / arrow-meta

Functional companion to Kotlin's Compiler
https://meta.arrow-kt.io
Apache License 2.0
395 stars 42 forks source link

Newtyping with Refined Types Support #21

Open raulraja opened 5 years ago

raulraja commented 5 years ago
@type typealias PositiveInt = Int with Positive<Int>

val x: PositiveInt = -1 //fails
val y: Validated<Not<Positive>, Positive<Int>> = PositiveInt(maybePositive)
@type typealias Option<A> = Either<Unit, A> with Monad<EitherPartialOf<Unit>>

Option is automatically materialized as a new type which combines the runtime of Either alongside its Monad API as synthetic injected methods

pakoito commented 5 years ago

Does this use inline classes or?

raulraja commented 5 years ago

The idea is that this will take a class and creates a new class which includes the instances and derivation all in one step:

@type typealias ListK<A> = List with Monad<ForListK>

Is the entire declaration for the ListK implementation. At the same time if you try to create impossible types:

@type typealias MyValidated<E, A> = Validated<E, A> with Monad<ValidatedPartial<E>>
// compiler bails because it can't find `flatMap` on `Validated` from which to derive Monad.

@pakoito this is equivalent to the impossible types in TypeclassLess but it manages the collisions and overrides for you so you can focus on one line in the semantics.

It could use inline classes for primitive wrapped types though:

@type typealias CombinableString = String with Semigroup<String>

generates:

inline class CombinableString(val value: String) {
  companion object {
    val semigroup: Semigroup<String> = ...
  }
}