Skip to content

Instantly share code, notes, and snippets.

@Takhion
Forked from raulraja/TwitterHandle.kt
Last active February 20, 2020 15:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Takhion/7e78ad11f4831ed1b3f4b899bd955d39 to your computer and use it in GitHub Desktop.
Save Takhion/7e78ad11f4831ed1b3f4b899bd955d39 to your computer and use it in GitHub Desktop.
Type Refinements with Type Proofs in Kotlin
/* Coming up ~ April 2020 */
package test
import arrow.*
inline class TwitterHandle
@Suppress("NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS")
private constructor(val handle: String) {
companion object : Refined<String> {
override val validate: String.() -> Map<String, Boolean> = {
mapOf(
"Should start with '@'" to startsWith("@"),
"Should have length <= 16" to (length <= 16),
"Should not contain the word 'twitter'" to !contains("twitter"),
"Should not contain the word 'admin'" to !contains("admin")
)
}
}
}
/**
* Similar extensions can target Validation and Either not just nullable types
* Proofs `String` can be coerced safely into a TwitterHandle
*/
@Proof(TypeProof.Extension, coerce = true)
fun String.twitterHandle(): TwitterHandle? =
if (TwitterHandle.isValid(this)) TwitterHandle(this)
else null
val admin = "@admin"
val whatever = "@whatever"
/* Fails to Compile:
* "@adminxxxxxxxxxxxxxxxxxxxxxxxx" is not a valid TwitterHandle because:
* e: Should not contain the word 'admin'
* e: Should have length <= 16
*/
TwitterHandle("@adminxxxxxxxxxxxxxxxxxxxxxxxx")
TwitterHandle("@whatever")
//TwitterHandle("@whatever")
val ok: TwitterHandle = "@whatever"
//TwitterHandle("@whatever") //ok
val nullableOk: TwitterHandle? = "@whatever"
//TwitterHandle("@whatever")
val runtimeAdminWillBeNull: TwitterHandle? = admin
//null
val runtimeWhateverIsValidated: TwitterHandle? = whatever
//TwitterHandle("@whatever")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment