2

f# で巡回多項式ハッシュ関数を実装しようとしています。ビット単位の演算子 ^^^ と <<< を使用します。配列をハッシュする関数の例を次に示します。

let createBuzhash (pattern : array<'a>)  =
let n = pattern.Length
let rec loop index pow acc =
    if index < n then
        loop (index+1) (pow-1) (acc ^^^ ((int pattern.[index]) <<< pow))
    else
        acc
loop 0 (n-1) 0

私の問題は、 の型'aが に制約されることですがint、この関数は、ビット単位の演算子で機能する任意の型 (たとえば、char. を使用してみinlineましたが、ライブラリのさらに下の方で問題が発生します。を使用せずにこれを修正する方法はありinlineますか?

わかりやすくするために編集: 関数はライブラリの一部になり、ビット単位の演算子をサポートしない型には別のハッシュ関数が提供されます。この関数を数値型および/または文字の配列で動作させたいです。

編集2(問題解決):インラインの問題は、ライブラリから関数をロードする方法でした。それ以外の

let hashedPattern = library.createBuzhash targetPattern

私はこのバインディングを使用しました:

let myFunction = library.createBuzhash
let hashedPattern = myFunction targetPattern

関数はライブラリ内の関数ですが、入力型myFunctionを int に制約します。関数の呼び出し方法を変更すると、型制約の問題が修正され、以下の回答が示すように完全に正常に動作します。createBuzhashinlineinline

4

1 に答える 1

3

int実装では、次のように関数を使用して配列の値を整数に変換しています。int pattern.[index]

これにより、配列要素の型に制約が作成され、「変換できるもの」である必要がありますint。関数を としてマークするとinline、実際には次のような型で機能し、次のcharように記述できます。

createBuzhash [|'a'; 'b'|]

ただし、この関数を使用して整数に変換できない型は他にもたくさんありintます。

これを任意の型で機能させるには、数値ではない型をどのように処理するかを決定する必要があります。あなたは__したいですか:

  • すべての値に対して独自のハッシュ関数を提供しますか?
  • 組み込みの .NETGetHashCode操作を使用しますか?
  • 関数を数値型と数値型の配列でのみ機能させますか?

1 つのオプションは、変換方法を指定するパラメーターを追加することです。

let inline createBuzhash conv (pattern : array<'a>)  =
  let n = pattern.Length
  let rec loop index pow acc =
      if index < pattern.Length then
          loop (index+1) (pow-1) (acc ^^^ ((conv pattern.[index]) <<< pow))
      else
          acc
  loop 0 (n-1) 0

を呼び出すときcreateBuzhashに、要素をハッシュする関数を指定する必要があります。これは、次の関数を使用してプリミティブ型でint機能します。

createBuzhash int [| 0 .. 10 |]
createBuzhash int [|'a'; 'b'|]

ただし、組み込みの F# ハッシュ メカニズムを使用することもできます。

createBuzhash hash [| (1,"foo"); (2,"bar") |]

また、関数をそれ自体に渡すことで、ネストされた配列を処理することもできます。

createBuzhash (createBuzhash int) [| [| 1 |]; [| 2 |] |]
于 2016-09-27T14:32:57.320 に答える