8

このアクティブなパターンはF#2.0でコンパイルされます。

let (|Value|_|) value = // 'a -> 'T option
  match box value with
  | :? 'T as x -> Some x
  | _ -> None

ただし、F#3.0では、次のエラーが発生します。

アクティブパターン'|値|_|' 入力によって決定されない型変数を含む結果型があります。一般的な原因は、結果のケースが言及されていない場合の[原文のまま]です。たとえば、'let(| A | B |)(x:int)=Ax'です。これは、型制約で修正できます。たとえば、'let(| A | B |)(x:int):Choice = A x'

私は試した:

let (|Value|_|) value : 'T option = ...

と:

let (|Value|_|) (value: 'U) = ...

どうすれば修正できますか?

環境:Visual Studio 2012(RTM)およびFSI v11.0.50727.1

編集:これはより簡単な再現です:

let (|X|) x = unbox x
4

4 に答える 4

4

F#2.0コンパイラにバグがあり、コンパイラが結果に自由型変数を含む特定のアクティブパターンに対して誤った分析と不正なコード生成を行っていました。単純な再現は

let (|Check|) (a : int) = a, None
//let (|Check|) (a : int) = a, (None : int option)

let check a = 
    match a with
    | Check (10, None) -> System.Console.WriteLine "10"
    | Check (20, None) -> System.Console.WriteLine "20"

check 10
check 20

これはコンパイル時に奇妙な警告を生成し、一見正しくないコードにコンパイルされます。F#3.0でこのバグを修正する(そしていくつかのクレイジーなケースを制限する)試みも、修正の巻き添え被害としていくつかの法典を破ったと私は推測しています。

別のバグを報告しますが、F#3.0の場合、他の回答に記載されている回避策の1つを使用する必要があるようです。

于 2012-08-16T16:51:29.263 に答える
3

私はまだ新しいバージョンをインストールしていませんが、これは少し怪しいように見えることに同意します。この制限には十分な理由があると思いますが、他の質問の例は非常に説得力があるようです。

回避策として、ウィットネスパラメーター(使用されていませんが、結果のタイプがどうなるかを示唆します)を追加すると機能すると思います。

let (|Value|_|) (witness:unit -> 'T) value : 'T option =
  match box value with 
  | :? 'T as x -> Some x 
  | _ -> None 

もちろん、これは使用を少し醜くします。なぜなら、いくつかの議論を思い付く必要があるからです。unit -> 'T上記では、以下がコンパイルされることを期待して、タイプのウィットネスを使用しました。

let witness () : 'T = failwith "!"

match box 1 with 
| Value witness 1 -> printfn "one"

それが機能しない場合は、おそらくタイプのwitnessパラメーターを使用してみることができます'T(ただし、ジェネリック関数だけでなく、実際の関数を提供する必要があります)。

于 2012-08-16T15:12:46.073 に答える
2

完全を期すために、もう1つの回避策:

type Box<'R> = Box of obj

let (|Value|_|) ((Box x) : Box<'R> ) : 'R option =
  match x with 
  | :? 'R as x -> Some x 
  | _ -> None 

let check t =
    match Box t with
    | Value 1 -> printfn "one"
    | Value 2 -> printfn "two"

check 1 // one
check 2 // two

ただし、別のスレッドで@kvbによって言及された問題が引き続き発生します。個人的には、パラメータ化されたアクティブパターンを備えた@kvbのバージョンを好みます。

于 2012-08-16T23:25:51.893 に答える
0

この問題を回避する方法に関するいくつかの考えと、そのようなアクティブなパターンが望ましくない可能性がある1つの理由については、他の質問に対する私の回答を参照してください。重大な変更が意図されたものかどうかはわかりません。

于 2012-08-16T15:38:47.127 に答える