Validating input with a scala system

Now playing a bit with Scala, I wonder how you should perform input validation in Scala.

This is what I saw many times:

def doSomethingWithPositiveIntegers(i: Int) = {
    require(i>0)
    //do something
}

to get the hang of it, it looks like it's done in Java:

void doSomething(Object o) {
    if (!o instanceof Integer)
        throw new IllegalArgumentException();
}

There you first accept more than you are willing to accept, and then introduce some kind of "guard" that allows only the "good." More precisely, you will need these guards in every function that does something with positive integers, and if you want, for example, to enable zero later, you will need to change each function. Of course, you can transfer it to another function, but, nevertheless, you always need to remember that you are calling the correct function, and it may not be able to survive type refactoring, etc. Doesn't sound like I would have this. I was thinking about pushing this verification code to the data type itself, for example:

import scala.util.Try

object MyStuff {
    implicit class PositiveInt(val value: Int) {
        require(value>0)
    }
    implicit def positiveInt2Int(positiveInt: PositiveInt): Int = positiveInt.value
}

import MyStuff._

val i: MyStuff.PositiveInt = 5
val j: Int = i+5
println(i)  //Main$$anon$1$MyStuff$PositiveInt@3a16cef5
println(j)  //10
val sum = i + i
println(sum)    //10

def addOne(i: MyStuff.PositiveInt) = i + 1

println(Try(addOne(-5)))    //Failure(java.lang.IllegalArgumentException: requirement failed)
println(Try(addOne(5)))     //Success(6)

PositiveInt, , () , Int. , API , - , ! , , , - . - ! , ( URL-, ).

:

  • API , ( do(String, String, String), do(User, Email, Password))
  • ""
  • . , , . :

    def makeNegative(i: PositiveInt): NegativeInt = -i
    addOne(makeNegative(1)) //will create a compile-time error!
    

:

  • , , - . , :

    val i: PositiveInteger = 5
    val range = i to 10        //error: value to is not a member of this.MyStuff.PositiveInt
    val range = i.value to 10  //will work
    

    , Int require, PositiveInt Int ( !), Int :). , , .

  • . , ( - , ?).

:

  • - ? , - , , . , .
  • ?
  • implicits ( # 1)? , - , (: PositiveInt RichInt)?
+4
1

, - factory, .

class PositiveInt private[PositiveInt](val i: Int)

object PositiveInt {
    def apply(i: Int): Option[PositiveInt] = if(i > 0) Some(new PositiveInt(i)) else None
}

PositiveInt , apply, , .

-1

All Articles