特定の方法で関数を構成したいと思います。これらの 2 つの関数を疑似コードで検討してください (F# ではありません)。
F1 = x + y
F2 = F1 * 10 // note I did not specify arguments for F1, 'reverse curry' for lack of a better word
私が F# でやりたいことは、それを理解することです。
let F1 x y = x + y
//val F1 : int -> int -> int
コードlet F2 = F1 * 10
は F1: と同じ署名を与えval F2 : int -> int -> int
、呼び出しF2 2 3
は 50: (2 + 3) * 10 になります。それはかなり賢いでしょう...
何が起こるかはかなり異なります。最初の行は期待どおりです。
let F1 x y = x + y
//val F1 : int -> int -> int
しかし、2 行目を追加すると、let F2 = F1 * 10
F# がスローされます。the type int does not match the type 'a -> 'b -> 'c
それはそれとそのF1を今訴えていrequires member ( + )
ます。
もちろん、次のように綴ることもできます。
let F1(x, y) = x + y
let F2(x, y) = F1(x, y) * 10
しかし、今では C# を使ったほうがよかったかもしれません。タプルされた引数は、F# の優雅さの多くを壊します。また、私の実際の関数 F1 と F2 には 2 つだけよりも多くの引数があるため、これはまさに私が F# を使用して回避したかったことと同じです。次のように言うと、より自然になります。
let F1 x y = x + y
let F2 = F1 * 10
私が(ほぼ)それを行う方法はありますか?
追加のクレジット: これらのエラー メッセージは正確にどうなっているのですか? let F2 = F1 * 10
2 行目で 1 行目の入力が変わるのはなぜですか?
ご意見ありがとうございます。
ゲルト・ヤン
update 説明されていることを (ほぼ) 実行する 2 つのアプローチ。
タプルを使用するもの。2 行目は少し風変わりに見えますが、問題なく動作します。小さな欠点は、現在カリー化を使用できないか、さらに風変わりなコードを追加する必要があることです。
let F1 (a, b) = a + b
let F2 = F1 >> (*) 10
F2(2, 3) // returns 50
別のアプローチは、レコードを使用することです。これはもう少し単純明快で、一見すると簡単に理解できますが、より多くのコードと式が必要になります。F# の優雅さの一部を取り除き、C# のように見えます。
type Arg (a, b) =
member this.A = a
member this.B = b
let F1 (a:Arg) = a.A + a.B
let F2 (a:Arg) = F1(a) * 10
F2 (Arg(2, 3)) // returns 50