中置演算子に対する部分適用の2パターン
HaskellWikiを読んでいたところ、よくわからない例を発見。
Apply a list of functions to a single element to get a list of results.
It's not in the book, but it's easy when you know how:
map ($ my_element) xs
つまり、次のように書くことで、一つの値に対して複数の関数を適用した結果のリストが得られる。
map ($ 1) [sin, cos, tan] -- => [0.7071067811865475,0.7071067811865476,0.9999999999999999]
どうやら($ 1) f
はf $ 1
と解釈されるらしい(ちなみに$
は最も優先順位が低いことから、式の評価順序を制御する区切りとして用いられる。ここではf $ 1 == f 1
である)。
実際にGHCiで型を調べてみても、f
を受け取って適用する場合の形となっている。
Prelude> :t ($ 1) ($ 1) :: Num a => (a -> b) -> b
どうしてこのように解釈されるのか調べたところ、これはSectionと呼ばれる構文とのこと。
Sectionは次のような糖衣構文であり、それぞれ右辺のように解釈される。ここでop
は+
や$
などの中置演算子である。
(e op) == \x -> e op x (op e) == \x -> x op e
累乗演算を例に表すと、下記のようになる。
(2 ^) 10 == 2 ^ 10 == 1024 (^ 2) 10 == 10 ^ 2 == 100
普通の関数の部分適用も似た形をしているため、少しややこしい。
実際、累乗演算子^
を前置演算子(^)
として書いた場合は、次のようになる。
((^) 2) 10 == (^) 2 10 == 2 ^ 10 == 1024
Sectionがあることで、HaskellではCommon Lispの1+
のような関数が自然に書ける。
map ($ 2) [(3+), (3-), (3*), (3/), (/3)] -- => [5.0,1.0,6.0,1.5,0.6666666666666666]