Rokiのチラ裏

学生による学習のログ

haskell $ 演算子の挙動

プログラミング言語 Haskell における演算子$に関するメモ。 次の関数  f(x, y) は指定範囲の数列のうちの偶数の二乗の総和を求める関数である。

f x y = sum $ map (^2) $ filter even [x..y]
g x y | x < y = f x y | x > y = f y x

main = print $ g 1 10

これは次のコードと等価である。

f x y = ((sum) (map (^2) (filter even [x..y])))
g x y | x < y = f x y | x > y = f y x

main = print $ g 1 10

$は以下の実行結果が示すように GHC.Base モジュールで定義されている。

Prelude> :i ($)
($) ::
  forall (r :: GHC.Types.RuntimeRep) a (b :: TYPE r).
  (a -> b) -> a -> b
        -- Defined in ‘GHC.Base’
infixr 0 $

執筆時現在の定義*1*2は以下の通りである*3

infixr 0  $, $!

--- 略

{-# INLINE ($) #-}
($) :: forall r a (b :: TYPE r). (a -> b) -> a -> b
f $ x =  f x

上記定義の通り、$演算子は関数とその引数を受け取りその引数を関数に転送する。また優先レベルは 0 であり右に結合する。以上の定義を参考に次のコードの評価順序を順にシミュレートする。

f x y = sum $ map (^2) $ filter even [x..y]

$ は優先順位が最も低いので以下のように括弧がつく。

f x y = (sum) $ (map (^2)) $ (filter even [x..y])

$は右に結合するので以下のように括弧がつく。

f x y = (sum) $ ((map (^2)) $ (filter even [x..y]))

$を消去して以下の式に納まる。

f x y = ((sum) ((map (^2)) (filter even [x..y])))