fugafuga.write

日々のログ

すごいH本 part23

$を使った関数適用

関数適用 = 関数呼び出しのこと

括弧の数を少なくしたい場合に役に立つらしい

*Main> :t ($)
($) :: (a -> b) -> a -> b

普通の関数適用は左結合

f a b c

は、

((f a) b) c)

となるので、(f a)から適用される。

$を使わない例

*Main> sum (map sqrt [1..130])
993.6486803921487

*Main> sum map sqrt [1..130]
-- (sum map) しようとしたが、左結合なのでエラーになる
<interactive>:130:5: error:
    • Couldn't match type ‘[b0]’ with ‘[t0] -> t’
      Expected type: (a0 -> b0) -> (a1 -> a1) -> [t0] -> t
        Actual type: (a0 -> b0) -> [a0] -> [b0]
    • In the first argument of ‘sum’, namely ‘map’
      In the expression: sum map sqrt [1 .. 130]
      In an equation for ‘it’: it = sum map sqrt [1 .. 130]
    • Relevant bindings include it :: t (bound at <interactive>:130:1)

$を使う例

*Main> sum $ map sqrt [1..130]
993.6486803921487

$は最も低い適用優先順位を持つ。$が出てきたらその右側の式が左側の関数に引数として渡される。

別の例、3 + 4 + 9 の平方根が欲しい

-- こうではなく
*Main> sqrt 3 + 4 + 9
14.732050807568877
-- こうしないといけない
*Main> sqrt (3 + 4 + 9)
4.0

$を使って書く

*Main> sqrt $ 3 + 4 + 9
4.0

また別の例、

*Main> sum (filter (> 10) (map (*2) [2..10]))
80

ホヮー、括弧がいっぱいだ! ひどい!

とのこと。

$を使って書き直す

*Main> sum $ filter (> 10) (map (*2) [2..10])
80

まだいけそう

*Main> sum $ filter (> 10) $ map (*2) [2..10]
80

括弧を削除する話とは別に、$は関数適用それ自身を関数として扱えるようにするために使える。

ちょっと何言ってんのかわかんないので、実際に見てみる。

*Main> map ($ 3) [(4+), (10*), (^2), sqrt]
[7.0,30.0,9.0,1.7320508075688772]

1引数を取る部分適用された関数のリストを、3 に適用している。

*Main> :t ($ 3)
($ 3) :: Num a => (a -> b) -> b

関数を引数にとって、その関数を 3 に適用する

*Main> ($ 3) (4 +)
7

こういうことか?

所感

括弧が少なくなって確かに見やすくなる。が、最後の例はイメージするのが難しい。

すごいHaskellたのしく学ぼう!

すごいHaskellたのしく学ぼう!

  • 作者: MiranLipovaca
  • 出版社/メーカー: オーム社
  • 発売日: 2017/07/14
  • メディア: Kindle版
  • 購入: 4人 クリック: 9回
  • この商品を含むブログを見る