趣味でElm触ってて、よく分かんないけどなんか動くみたいな感じでやってる、関数型言語素人のダイナミックHTMLコーダーである私目線の内容です。
なので、浅学者が関数型を語るとアツくなってしまうタイプの方はどうかこの先を読まないでください![]()
さて本題に入りますが、Elmは関数を適用するときに()を使わない言語です。
JSで、
func(arg)
というのはElmでは
func arg
と書きます。
しかしこんなJSコード
func1(func2(arg))
をElmで表現しようとするとき、
func1 func2 arg
と書くと違う挙動になります。これは
func1(func2)(arg)
に相当してしまいます。
Elmは算数の式の優先順位を付ける感じで()を使えるので、
func1 (func2 arg)
と書くのが正解です。
が、熟練のElmersのコードを見てもこの書き方はあまり見かけないんですよね。
その代わりこういうのよく見るんです。
func1 <| func2 arg
<|ってなんだよ魚の頭かよキメぇなとか思いながらドキュメント読んで気づきました。
あれ、func1 <| func2 argってfunc1 (func2 arg)だったんすかと。
<|ってなんだよ
ドキュメントによると<|は後方関数適用(なんだそれ?)する関数で、こういうことなんだそうです。
[(<|)](http://package.elm-lang.org/packages/elm-lang/core/5.1.1/Basics#<|) : (a -> b) -> a -> b
Elmの型の見方を簡単に説明すると、
Intは「Intを返す関数」
Int -> Stringは「Intを引数にとりStringを返す関数」
Bool -> Int -> Stringは「BoolとIntを引数にとりStringを返す関数」
(Bool -> Int) -> Stringは「「Boolを引数にとりIntを返す関数」を引数にとりStringを返す関数」
と読めばいいみたい。また、型のとこをaみたいに小文字で書くと型変数になってジェネリックになるみたい。
ということで、<|とは、「任意型aを引数にとって任意型bを返す関数」と「同じ型a」を引数にとって「同じ型b」を返す関数です!なるほどわからん!
私ほどの高卒ヒモ野郎になるとガチで言っている意味がわからないのですが、要は関数適用のエイリアスなんだそうです。
しかも中置関数っつって、引数の間に書ける関数なんだそうです。自由だなぁ。
つまりfunc arg == (<|) func arg == func <| argなんだって。
これだと使う意味なさげだけど、func1 (func2 arg)だと<|使えば、
評価の順番が変わるとかでfunc1 <| func2 argと()無くせてCoolっつうわけですかね。
実際のところ、Elmにはタプルって型が(a, b)みたいな文法なので、それと混同して紛らわしいから確かに()使わない方がわかりやすいかも。
そして、この魚の頭には、前方関数適用する右バージョンもあります。ヒラメとカレイ的なことかな。
(|>) : a -> (a -> b) -> b
func arg == (|>) arg func == arg |> funcということらしい
func1 (func2 arg)をfunc2 arg |> func1と書くかfunc1 arg <| func2と書くかだけの違いだと思うんですけど、熟練Elmersの傾向としては、
func1 (func2 (func3 (func4 (func5 (func6 arg)))))みたいに適用しまくってる時は
func6 arg
|> func5
|> func4
|> func3
|> func2
|> func1
みたいな感じでカレイを使ってるのをよく見る気がします。
JSのPromiseのチェーンみたいな感じで割としっくりくるかも。
まとめ
ふーん、まぁ、よくわかんないけど、そう書きゃいいのね、って感じの知能ではありますが、
とりあえず()つけないことがカッコいいっていう、その生き様にはシンパシーを感じた、という話。