How to make "nm" a limited version of int in Scala?

I would like to have types sa Int_1to3or Uintin Scala. Preferably, there will be a generic factory method that anyone can provide.

This is mainly for self-documented purposes, but also the values ​​will be checked upon arrival (ie via "assert").

I was somewhat surprised that I did not find a solution for this during my initial (google) search. The closest I came to is Unsigned.scala , but this one is redundant for my needs.

Should it be dead just?

Just to give an idea of ​​usage, something like this would be great! :)

type Int_1to3= Int_limited( 1 to 3 )
type Uint= Int_limited( _ >= 0 )
+5
source share
5 answers

I see two possible solutions:

Unboxed Type Tags. . , , .

- :

type Tagged[U] = { type Tag = U }
type @@[T, U] = T with Tagged[U]

trait Positive
trait One2Three

type PositiveInt = Int @@ Positive
type SmallInt = Int @@ One2Three

//Builds a small int
def small(i: Int): SmallInt = {
  require( i > 0 && i < 4, "should be between 1 and 3" )
  i.asInstanceOf[SmallInt]
}

//Builds a positive int
def positive( i: Int): PositiveInt = {
  require( i >= 0, "should be positive" )
  i.asInstanceOf[PositiveInt]
} 

//Example usage in methods
def mul( i: SmallInt, j: PositiveInt ): PositiveInt = positive(i*j)

REPL:

scala> mul( small(2), positive(4) )
res1: PositiveInt = 8

scala> mul( small(4), positive(2) ) //RUNTIME ERROR
java.lang.IllegalArgumentException: should be between 1 and 3


scala> mul( 2, positive(2) )       //COMPILE TIME ERROR
<console>:16: error: type mismatch;
 found   : Int(2)
 required: SmallInt
              mul( 2, positive(2) )
                   ^

, Scala 2.10. SIP-15, , .

+4

"", , , , . ,

sealed abstract class Int_1to3(val i:Int)
object Int_1to3 {
  def apply(i:Int):Option[Int_1to3] =
    if (1.to(3).contains(i)) Some(new Int_1to3(i){}) else None
}

, , x Int_1to3, , x.i 1, 2 3.

+2

" ", :

def safeInt(i: Int, f: Int => Boolean): Int =
  if (f(i)) i else throw new IllegalArgumentException("wrong int")

def int1to3(i: Int) =
  safeInt(i, 1 to 3 contains _)

def uInt(i: Int) =
  safeInt(i, _ >= 0)

, , . , , , .

+1

, . - - , "overkilL".

0

Scalatest/Scalatric 3.0, @- PosInt, PozInt, , 2012 .

OddInt , .

0
source

All Articles