8

正常に機能するコードは次のとおりです。

let f x y z = x + y + z

let g x y = f x y
let h x z = z |> f x

したがって、式「h 1」を記述でき、FSIは次のように表示します。

val it : (int -> int -> int) = <fun:it@110-3>

「h123」と呼ぶと、引数は正しい順序で適用されます。
しかし、最後の引数のタイプが異なる場合、状況は異なります。

let ff x y (z : string) = x + y

let gg x y = ff x y
let hh x (z : string) = z |> ff x

ここで、最後の関数hhによりエラーメッセージが表示されます。

Script.fsx(119,10):エラーFS0001:タイプの不一致。期待しているstring -> 'a が与えられたint -> string -> int。タイプがタイプstringと一致しませんint

これが発生する理由を理解しています。「z」が「ffx」に追加され、2番目の引数になります。しかし、最初の例では、式「h 1 2 3」が正しく機能しない(「f 1 3 2」として実行される)と予想します。しかし、それはうまく機能します。

4

1 に答える 1

9

関数ffとこのgg例では同じです。パイプライン演算子は、右側の関数の最初の引数に値を提供します。あなたの例では、右側の関数はでff xあり、パイプライン演算子を使用して、引数の値を指定しますy

let ff x y (z : string) = 
  printfn "%s" z
  x + y

// These two functions are the same:
let gg x y = ff x y
let hh x y = y |> ff x

部分機能アプリケーションを使用する場合、最初のパラメーター以外を指定するための標準構文はありません。ただし、それを行うために高階関数またはカスタム演算子を作成できます。例えば:

// Takes a function 'f' of type 'b -> 'a -> 'c
// and a value 'v' of type 'a and creates a function
// that takes the first argument ('b -> 'c)
let (|*>) v f = (fun mid -> f mid v);;

let gg x y = ff x y     // Specifies arguments x and y
let hh x z = z |*> ff x // Specifies arguments x and z

|*>1つの引数をスキップすることを示すために、演算子に名前を付けました。他の引数の値を同様に指定する演算子を定義できます(たとえば|**>、最初の2つの引数をスキップします)。

于 2010-07-07T13:24:11.843 に答える