の演算子オーバーロードを定義するレコード型で List.fold を使用しようとしていますが、fold に渡されたラムダとして演算子+
を使用しようとすると、型の不一致エラーが発生します。(+)
私の問題を例示する単純化されたスニペットは次のとおりです。
// a record type that also includes an overload for '+'
type Person =
{ Name : string; Age: int }
static member ( + ) (x: Person, y: Person) = x.Age + y.Age
オーバーロードは+
うまく機能します
> jen + kevin;;
val it : int = 87
しかし、私が人のリストを持っているとしましょう:
> let people = [kevin;jen];;
List.fold を使用してすべての年齢を合計することはできません。
> List.fold (+) 0 people;;
List.fold (+) 0 people;;
----------------^^^^^^
error FS0001: Type constraint mismatch. The type
int
is not compatible with type
Person
The type 'int' is not compatible with the type 'Person'
アキュムレータとして '0' を使用したため+
、fold が暗黙的にリストを入力しているため、F# がこの方法で渡されたときのオーバーロードを識別できないことが問題であると推測しています。int
カスタム オペレーターのオーバーロードを正しく機能させることができるかどうか、また可能であれば、それを実現するために何が欠けているかはわかりません。+
(フロートで使用できるため、これを機能させることができると思います)。
編集
問題は型の不一致であることを理解しています。JaredPar が書いているように、ラムダを記述して 2 人の人物のレコードを取得し、年齢を追加できることがわかりました。それは私の主張ではありません。+
問題は、私が既に書いた演算子のオーバーロードを有効なオーバーロードとしてフォールドによって認識されるようにする方法があるべきだと私には思われることです。
別の編集
ご意見をお寄せいただきありがとうございます。明らかになりつつあることの 1 つは、自分のやりたいことができないということですが、それは問題ありません。私は何かを学びました!私が見ているのは、演算子のオーバーロードの解決は、すべてのコンテキストで機能するとは限らないということです。そのため、ラムダとして渡されたものを、インフィックス ala として使用した場合と同じように機能させるシームレスな方法fold
はありません。これが正しく機能しない理由は完全に理にかなっています。この問題を解決するために人々が提案した解決策は、基本的に特定の問題を処理するための 1 回限りのものです。+
jen + kevin
fold
foldback
など) -- リストを操作するために、特別なケースのコードをたくさん書く必要はありませんでした。F# の演算子のオーバーロードの解決には、表面的なレベルまで動作させるいくつかの制限があることは明らかですが、これは問題ありません。