もう少し複雑な関数を書いているとき、それ$
がよく使われていることに気づきましたが、それが何をするのかわかりませんか?
2 に答える
$
中置「アプリケーション」です。それは次のように定義されています
($) :: (a -> b) -> (a -> b)
f $ x = f x
-- or
($) f x = f x
-- or
($) = id
余分な括弧を避けるのに便利です: f (g x) == f $ g x
.
特に便利な場所は、次のような「末尾のラムダ本体」です。
forM_ [1..10] $ \i -> do
l <- readLine
replicateM_ i $ print l
に比べ
forM_ [1..10] (\i -> do
l <- readLine
replicateM_ i (print l)
)
または、トリッキーなことに、「この引数を任意の関数に適用する」を表現するときに、セクション化されて表示されることがあります
applyArg :: a -> (a -> b) -> b
applyArg x = ($ x)
>>> map ($ 10) [(+1), (+2), (+3)]
[11, 12, 13]
私は、$ 記号を括弧の代わりと考えるのが好きです。
たとえば、次の式:
take 1 $ filter even [1..10]
-- = [2]
$ を付けないとどうなりますか? 次に、取得します
take 1 filter even [1..10]
コンパイラは、take
引数が1 :: Int
, filter :: (a -> Bool) -> [a] -> [a]
, .even :: Integral a => a -> Bool
[1..10] :: [Int]
これは明らかに間違っています。では、代わりに何ができるでしょうか。さて、式を括弧で囲むことができます:
(take 1) (filter even [1..10])
これは次のようになります。
(take 1) ([2,4,6,8,10])
これは次のようになります。
take 1 [2,4,6,8,10]
しかし、常に括弧を書きたいとは限りません。特に、関数が互いに入れ子になっている場合はなおさらです。別の方法として、括弧のペアの間に記号を配置する方法が$
あります。この場合は次のようになります。
take 1 $ filter even [1..10]