8

次のような表現は可能ですか?

type id = int > 0

F#には依存型があることを意味するため、静的に実行することは不可能です。C#では、コードコントラクトを使用してこの種のことを行い、ランタイムの強制を取得することに慣れています。ここで似たようなものを探しています。

ありがとう

編集:さまざまな長所と短所を持っているすべての答えをありがとう。モネントでは、F#の小さなサブセットのみを使用しています。これは、証明をプログラムするのに簡単に役立つocamlコアのサブセットです。したがって、クラスはありません。

4

4 に答える 4

8

他の人が言ったこととは反対に、あなたの問題を正しく理解していれば、ここではクラスを使用しないことをお勧めします。
値は不変であるため、制約を適用する必要があるのは1回だけです。すべてのラッパークラスはオーバーヘッドであり、GCをロードします。代わりに、単純な関数がその役割を果たします。

let inline constrained predicate errormessage value =
    if not (predicate value)
    then invalidArg "value" errormessage
    else value

let positive =
    constrained (fun x -> x > 0) "Value must be positive"

let int1 = positive 5      // OK
let int2 = positive -3     // ArgumentException

他のタイプでも同じことができます。

let mustBeLong =
    constrained (fun (x:string) -> x.Length > 3) "String must be long"

let str1 = mustBeLong "foobar"  // OK
let str2 = mustBeLong "baz"     // ArgumentException

構造体内で同じものを使用する:

type Point2D =
   struct 
      val X: int
      val Y: int
      new(x: int, y: int) = { X = positive x; Y = positive y }
   end

let point1 = Point2D(5, 3)  // OK
let point2 = Point2D(5, -2) // ArgumentException
于 2012-12-30T20:09:07.197 に答える
4

ユニオン型として定義します。

type Id = Id of int

コンストラクターを別の関数でシャドウします。

let Id n =
  assert(n > 0)
  Id n
于 2012-12-31T16:48:21.597 に答える
2

F# では、クラスに頼って、コンストラクター内の引数をチェックする必要があります。判別共用体、レコード、構造体などの他の型には、簡単に変更できない暗黙のコンストラクターがあります。

type Id(i: int) =
    do if i <= 0 then 
         invalidArg "i" "the argument has to be a positive integer"
    member x.Value = i

パターン マッチングは、クラスではうまく機能しません。アクティブなパターンを使用して問題を解決できます。

let (|Id|) (id: Id) = id.Value

let id = Id(1)

match id with
| Id 1 -> printfn "matched"
| _ -> printfn "unmatched"
于 2012-12-30T17:14:38.027 に答える
1

次のようなジェネリック クラスを作成できます。

type verify<'t>(t:'t,cond) =
    let mutable tval = t
    let _verify v = if not (cond v) then failwith "bad argument"
    do _verify tval
    member x.get() = tval
    member x.set v =
        _verify v 
        tval <- v

その後、あなたはそれを使用することができます

verify(1,fun t -> t>0)

を使用.setして状態を再確認します。

于 2012-12-30T10:44:49.760 に答える