La définition de la fonction:
applyAll = \fs -> \x -> map(\n -> n x) fs
est le même que:
applyAll fs x = map(\n -> n x) fs
Maintenant, vous pourriez demander: « Quels sont les ->
s font là-bas si elles ne sont que des arguments à ma fonction applyAll
.Haskell n'a pas de concept de fonctions multi-param. Ce que vous voyez comme des arguments multiples à une fonction est juste de nombreuses fonctions enchaînées ensemble chaque avec un seul argument. Dans le cas de applyAll
, il est juste deux fonctions enchaînées ensemble:
(applyAll fs) -> x = map (\n -> n x) fs
applyAll fs
une seule fonction à un autre argument enchaîné identifié comme x
pour obtenir une liste des valeurs renvoyées par map
.
Je pourrais essayer dans ghci:
Prelude> :t applyAll
applyAll :: [t -> b] -> t -> [b]
Prelude> :t applyAll xs
<interactive>:1:10: Not in scope: `xs'
Prelude> let xs = [1..5]
-- hah, BOOM! I told you haskell's strongly typed...
Prelude> :t applyAll xs
<interactive>:1:10:
Couldn't match expected type `t0 -> b0' with actual type `Integer'
Expected type: [t0 -> b0]
Actual type: [Integer]
In the first argument of `applyAll', namely `xs'
In the expression: applyAll xs
Prelude> let xs = [(1 +), (2 +), (3 *), (4 /)]
Prelude> :t xs
xs :: [Double -> Double]
Prelude> :t applyAll xs
applyAll xs :: Double -> [Double]
Prelude> :t applyAll
applyAll :: [t -> b] -> t -> [b]
Prelude> :t applyAll xs 3
applyAll xs 3 :: [Double]
Prelude> applyAll xs 3
[4.0,5.0,9.0,1.3333333333333333]
Quel est le type de map
?
map :: (a -> b) -> [a] -> [b]
Cela me dit que map
prend une fonction - appelons-le f
et une liste de valeurs pour revenir une autre liste de valeurs. La fonction f
est une fonction qui prend une valeur de type a
en renvoyant une autre de type b
. Donc, map
continue d'appliquer f
à chaque valeur de la liste [a]
pour renvoyer une autre liste remplie de valeurs de type b
. Dans votre applyAll
, la fonction f
est \n -> n x
. Il s'agit d'une expression lambda (que vous pouvez appeler une fonction anonyme) prenant une valeur identifiée par n
et lui appliquant x
. Cela se poursuit pour chaque élément de la liste d'entrée identifié par [a]
dans la définition de type jusqu'à ce qu'il soit épuisé pour générer une autre liste identifiée par [b]
dans la définition de type.