5

タイプ saInt_1to3またはUintin Scala が必要です。できれば、そのようなものを提供できる一般的なファクトリメソッドがあるでしょう。

これは主に自己記録の目的のためですが、値は到着時に (つまり、'assert' を介して) チェックされます。

最初の (Google) 検索でこれに対する解決策が見つからなかったことに少し驚きました。最も近いのはUnsigned.scalaですが、それは私のニーズにはやり過ぎです。

これは非常に単純でなければなりませんか?

使い方のアイデアを言うと、このようなものは素晴らしいでしょう!:)

type Int_1to3= Int_limited( 1 to 3 )
type Uint= Int_limited( _ >= 0 )
4

5 に答える 5

4

考えられる解決策は 2 つあります。

最初に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) )
                   ^

2 番目の解決策は、Scala 2.10 用に提案された値クラスです。SIP-15を読んで、それらの使用方法を確認できます。

于 2012-09-04T09:54:05.113 に答える
2

ここで使用できる "パターン" は、プライベート コンストラクターを基になる値のラッパーとしてシールされた型を宣言することです。これは、検証およびインスタンス化できる単一のポイントに制限されます。例えば

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.i123

于 2012-09-04T04:59:02.593 に答える
1

このような「低い基準」があるため、次のことを行うだけで十分です。

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)

コードを安全に保つためにコンパイラを強制したくない場合、この aa 型を使用しても意味がありません。これは可能ですが、あなたが言ったように、あなたのニーズには合っていません。

于 2012-09-04T08:42:51.747 に答える
0

いいえ、その言語にはそのようなものはありません。ライブラリを介して利用可能なソリューションは、「overkilL」と呼ばれるものです。

于 2012-09-04T03:16:07.147 に答える
0

昨日、Scalatest/Scalatric 3.0のビデオを見て、その中で @Bill-Venners が、私が 2012 年に尋ねていたものに非常に近いPosInt,型について議論しました。PozInt

OddInt彼はまた、そのような値型を自分で作成するためのサンプルを提示しました。

于 2015-04-10T10:01:02.543 に答える