62

もう少し複雑な関数を書いているとき、それ$がよく使われていることに気づきましたが、それが何をするのかわかりませんか?

4

2 に答える 2

75

$中置「アプリケーション」です。それは次のように定義されています

($) :: (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]
于 2013-10-22T14:56:39.280 に答える
24

私は、$ 記号を括弧の代わりと考えるのが好きです。

たとえば、次の式:

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]

于 2016-05-14T15:25:41.483 に答える