question de la signature de type haskell
-
28-09-2019 - |
Question
Quelqu'un peut me expliquer, pourquoi ces fonctions ont nombre différent d'arguments et le comportement , mais la même signature de type , mais ils sont à la fois correcte?
comp1 :: (a -> b) -> (b -> c) -> a -> c
comp1 f g = g.f
comp2 :: (a -> b) -> (b -> c) -> a -> c
comp2 f g x = g (f x)
aussi, pourquoi COMP2 a
comp2 :: (a -> b) -> (b -> c) -> a -> c
au lieu de quelque chose comme
comp2 :: a -> (a -> b) -> (b -> c) -> a -> c
Merci.
La solution
comp2 f g x = g (f x)
est le sucre syntaxique pour
comp2 = \f -> \g -> \x -> g (f x)
De même
comp1 f g = g.f
est le sucre pour
comp1 = \f -> \g -> g.f
La définition de .
est:
f1 . f2 = \x -> f1 (f2 x) -- Names of arguments have been changed to avoid confusion
Donc, si l'on insère la définition dans la forme Dessucré de comp1
, nous obtenons:
comp1 = \f -> \g -> \x -> g (f x)
Ceci est exactement la même que la forme Dessucré de comp2
, si clairement les définitions sont équivalentes.
Autres conseils
comp1 f g = g.f
est écrit dans de style point libre (ne parle pas aux points, mais à valeurs ). Lorsque vous appelez comp1
, il est implicitement un troisième paramètre étant passé à g.f
, qui est la composition des deux fonctions g
et f
: (g.f) x
est égal à g (f x)
, à savoir g
est passé le résultat de f x
. Aucun paramètre x
existe dans comp1
car il est passé implicitement à la fonction. (Vous pourriez penser comp1
comme partiellement appliqué ou cari fonction si elle vous fait vous sentir mieux.)
type de comp2
demande deux fonctions, l'une et l'autre de (a->b)
(b->c)
, ainsi qu'un paramètre de type a
. Il n'y a pas besoin de mettre a ->
dans sa signature.
Les deux fonctions sont vraiment équivalentes; on utilise simplement quelques astuces Haskell pour être plus concis.
Currying . Une fonction multi-argument ML et Haskell, est simplement sucre syntaxique pour une fonction à un argument qui renvoie une fonction; la fonction qui renvoie prend les arguments restants.