1

単純な配列追加関数を作成しようとしています。唯一の複雑さは、それを一般的にしようとした私の試みから来ています。C#には値型の型制約がないことは知っていますが、F#では明示的なメンバー制約で機能させることができると理解しています。これが私の試みです:

let Add<'T when 'T : (member (+) : 'T -> 'T -> 'T)> (A : 'T[]) (B : 'T[]) =
    Array.init A.Length (fun i -> A.[i] + B.[i])

コンパイラーは3つのエラーをリストします。1つはA.[i]、1つは+記号、もう1つはB. [i]ですが、私の推測では、これらはすべて同じです。

A type parameter is missing a constraint 
'when  ^T : (static member ( + ) :  ^T *  ^T ->  ^?6069)'

これは単なる構文上の問題だと確信していますが、誰かが私を正しい場所に向けることができますか?

ps:これを行うための別の/より簡単な方法はありますか、それともこれを機能させるための正しい方法ですか?

4

1 に答える 1

6

関数をマークしますinline。その後、制約が推測されます。

let inline Add (A : 'T[]) (B : 'T[]) =
  Array.init A.Length (fun i -> A.[i] + B.[i])

関数は次のように書くこともできます。

let inline add a b = Array.map2 (+) a b

編集

制約を明示的にするために、これを行うことができます(これはひどいように見えます)

let inline Add< ^T when ^T : (static member (+) : ^T * ^T -> ^T) > (A : ^T[]) (B : ^T[]) =
    Array.init A.Length (fun i -> (^T : (static member (+) : ^T * ^T -> ^T) (A.[i], B.[i])))

ただし、警告が生成されます。

'op_Addition'という名前のメンバー制約は、特定の.NETタイプがこのメンバーで暗黙的に拡張されるため、F#コンパイラによって特別なステータスが与えられます。これにより、独自のコードからメンバー制約を呼び出そうとすると、実行時に失敗する可能性があります。

于 2013-02-15T20:56:20.927 に答える