F# memo

F#はOCamlの拡張にも見えるけど独特の関数適用、関数合成の 演算子が面白い.

関数適用

let (|>) x f = f x
let (<|) f x = f x

関数合成

let (>>) f g = fun x -> g (f x)
let (<<) f g = fun x -> f (g x)

上の2つは順次パイプライン演算と呼ばれ
下の2つは順次合成演算という
入力のしやすさよりも見た目の良さを優先させている観がある.

()で括った二項演算子は中間記法を前提としていて、つまり

x |> f と書いて f x を表す.

結合優先順位としては

(通常の関数適用) >> (|>) > (<<), (>>) > (<|)

左結合右結合は慣れればだいたい見た目通りに思える. 結合優先順位が若干曲者

使用例

let sq x = x * x
let add1 x = x + 1

(sq (add1 2))

これを次のように書く.

2 |> add1 |> sq

次はエラー

sq <| add1 <| 2

これは

(sq add1) 2

と解釈される.

括弧を補うならば

sq <| (add1 <| 2)

とするしかない. 左向きのパイプラインは関数合成を組み合わせるのが前提で(たぶん)

sq << add1 <| 2

とすると、

(fun x -> sq (add1 x)) 2

と解釈される.


右向きのパイプライン結合と左向きのパイプライン結合が キレイに左右対象になっていない.ちょっと嫌だ.

f,g,hという3つの関数にxという数を通す

f (g (h x))

をパイプラインで書くことを考えると

x |> h |> g |> f

これはxをhして、gして、fする、と考えたことと文章が一致 していてとてもいい.Haskellになどには(簡単に定義できる にしても)ない演算だ.

左向きのパイプラインでは

f << g << h <| x

となる.記号が左右対象にならない.