Qu’est-ce que $ signifie / fait dans Haskell?

Lorsque vous écrivez des fonctions un peu plus complexes, je remarque que $ est beaucoup utilisé mais je ne sais pas du tout ce qu’il fait?

$ est infixe “application”. Il est défini comme

 ($) :: (a -> b) -> (a -> b) f $ x = fx -- or ($) fx = fx -- or ($) = id 

C’est utile pour éviter les parenthèses supplémentaires: f (gx) == f $ gx .

Un endroit particulièrement utile pour cela est un “corps lambda traînant” comme

 forM_ [1..10] $ \i -> do l <- readLine replicateM_ i $ print l 

par rapport à

 forM_ [1..10] (\i -> do l <- readLine replicateM_ i (print l) ) 

Ou, de manière délicate, il apparaît parfois sectionné lorsqu’il exprime «appliquer cet argument à une fonction quelconque»

 applyArg :: a -> (a -> b) -> b applyArg x = ($ x) >>> map ($ 10) [(+1), (+2), (+3)] [11, 12, 13] 

J’aime penser au signe $ en remplacement de la parenthèse.

Par exemple, l’expression suivante:

 take 1 $ filter even [1..10] -- = [2] 

Que se passe-t-il si on ne met pas le $? Serait alors

 take 1 filter even [1..10] 

et le compilateur se plaignait maintenant, car il pensait que nous essayions d’appliquer 4 arguments à la fonction take , les arguments étant 1 :: Int , filter :: (a -> Bool) -> [a] -> [a] , even :: Integral a => a -> Bool , [1..10] :: [Int] .

Ceci est évidemment incorrect. Alors, que pouvons-nous faire à la place? Eh bien, nous pourrions mettre des parenthèses autour de notre expression:

(take 1) (filter even [1..10])

Cela ne réduirait pas à:

(take 1) ([2,4,6,8,10])

qui devient alors:

take 1 [2,4,6,8,10]

Mais nous ne voulons pas toujours écrire des parenthèses, surtout les fonctions commencent à être nestedes les unes dans les autres. Une alternative consiste à placer le signe $ entre la paire de parenthèses, ce qui serait:

take 1 $ filter even [1..10]