Last active
August 20, 2019 02:47
-
-
Save chuwy/a6be098a604da1ab255a436f6ecf5fdd to your computer and use it in GitHub Desktop.
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
/** Always positive integer, nobody can do `new PositiveInt(-3)` */ | |
class PositiveInt private(value: Int) extends AnyVal | |
/** Set of constructors for PositiveInt */ | |
object PositiveInt { | |
/** The only proper constructor. Everything else is workaround */ | |
def fromInt(int: Int): Option[PositiveInt] = if (int > 0) Some(new PositiveInt(int)) else None | |
/** | |
* This is a workaround and must be called ONLY when caller is sure the `int` is positive | |
* *Every function calling `unsafeFromInt` is unsafe by definition* | |
*/ | |
def unsafeFromInt(int: Int): PositiveInt = new PositiveInt(int) | |
} | |
object DownstreamModule { | |
/** Totally safe function, by contract. Cannot throw an exception */ | |
def repeat[A](element: A, index: PositiveInt): List[A] = ??? | |
// Let's imagine we want to get a sum of N integers (for some reasons by filling a list with it) | |
/** Ths is what we have now. It's still unsafe function */ | |
def invalid(value: Int, n: Int) = | |
repeat(value, PositiveInt.unsafeFromInt(n)).sum | |
/** This is what we should have. It is safe function - we don't care where we got PositiveInt from, we just assume its valid */ | |
def valid(value: Int, n: PositiveInt) = | |
repeat(value, n).sum | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment