Ceci a à voir avec l'analyse. Dans Haskell, vous pouvez écrire (op arg)
où op
est un opérateur infixe. Ce n'est pas la même chose que ((op) arg)
. Et vous pouvez aussi écrire (arg op)
! Par exemple:
GHCi, version 7.0.3: http://www.haskell.org/ghc/ :? for help
Prelude> :t (+ 4)
(+ 4) :: Num a => a -> a
Prelude> :t (4 +)
(4 +) :: Num a => a -> a
C'est, (+ 4)
est la fonction \x -> x + 4
et (4 +)
est la fonction \y -> 4 + y
. Dans le cas de l'addition, ce sont des fonctions égales, mais ce n'est pas vraiment important en ce moment.
Maintenant, nous allons essayer la même astuce sur $
:
Prelude> :t ($ [1,2,3,4])
($ [1,2,3,4]) :: Num t => ([t] -> b) -> b
Maintenant surprise, à ce jour, nous avons eu \f -> f $ [1,2,3,4]
. Nous pouvons également écrire
Prelude> :t (length $)
(length $) :: [a] -> Int
pour obtenir la fonction \l -> length $ l
. Mais qu'en est-il de:
Prelude> :t ($ length)
($ length) :: (([a] -> Int) -> b) -> b
Ceci est étrange, mais c'est logique! Nous avons obtenu \f -> f $ length
, c'est-à-dire, Une fonctionnelle qui attend d'obtenir une fonction f
de type ([a] -> Int) -> b)
qui sera appliqué à length
. Il y a une quatrième possibilité:
Prelude> :t ([1,2,3,4] $)
<interactive>:1:2:
Couldn't match expected type `a0 -> b0' with actual type `[t0]'
In the first argument of `($)', namely `[1, 2, 3, 4]'
In the expression: ([1, 2, 3, 4] $)
Tout est comme il devrait être parce que [1,2,3,4]
n'est pas une fonction. Que faire si nous écrivons $
entre parenthèses? Ensuite, sa signification particulière comme un opérateur infixe disparaît:
Prelude> :t (($) length)
(($) length) :: [a] -> Int
Prelude> :t (($) [1,2,3,4])
<interactive>:1:6:
Couldn't match expected type `a0 -> b0' with actual type `[t0]'
In the first argument of `($)', namely `[1, 2, 3, 4]'
In the expression: (($) [1, 2, 3, 4])
Prelude> :t (length ($))
<interactive>:1:9:
Couldn't match expected type `[a0]'
with actual type `(a1 -> b0) -> a1 -> b0'
In the first argument of `length', namely `($)'
In the expression: (length ($))
Prelude> :t ([1,2,3,4] ($))
<interactive>:1:2:
The function `[1, 2, 3, 4]' is applied to one argument,
but its type `[t0]' has none
In the expression: ([1, 2, 3, 4] ($))
Donc, pour répondre à votre question: $ [1,2,3,4]
est analysé comme \f -> f $ [1,2,3,4]
il est parfaitement logique de l'appliquer à length
. Cependant ($) [1, 2, 3, 4]
n'a pas beaucoup de sens car ($)
n'est pas vu comme un opérateur infixe.
Par ailleurs, $
ne « pas faire quoi que ce soit », pour ainsi dire. Il est principalement utilisé pour une entrée plus lisible car il a une faible priorité et donc nous pouvons écrire f $ g $ h $ x
au lieu de f (g (h x))
.
Il ne s'agit pas de '($)', mais des sections d'opérateur. – phg
'$' * ne retarde pas l'évaluation de la fonction à gauche. Vous pouvez le confondre avec '$!', Ce qui force l'évaluation partielle de l'argument à sa droite avant de l'envoyer à la fonction à sa gauche. – dave4420
C'est la syntaxe "section" au travail. http://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-300003.5 –