Haskell pregunta tipo de firma
-
28-09-2019 - |
Pregunta
Puede alguien explicar, ¿por qué estas funciones tiene número diferente de argumentos y el comportamiento , pero mismo tipo de firma , sin embargo, ambos son correctos?
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)
también, ¿por qué tiene comp2
comp2 :: (a -> b) -> (b -> c) -> a -> c
en lugar de algo así como
comp2 :: a -> (a -> b) -> (b -> c) -> a -> c
Gracias.
Solución
comp2 f g x = g (f x)
es el azúcar sintáctica para
comp2 = \f -> \g -> \x -> g (f x)
Del mismo modo
comp1 f g = g.f
es el azúcar para
comp1 = \f -> \g -> g.f
La definición de .
es:
f1 . f2 = \x -> f1 (f2 x) -- Names of arguments have been changed to avoid confusion
Así que si insertamos en la definición de la forma Desazucarado comp1
, obtenemos:
comp1 = \f -> \g -> \x -> g (f x)
Esto es exactamente la misma que la forma Desazucarado de comp2
, tan claramente las definiciones son equivalentes.
Otros consejos
comp1 f g = g.f
está escrito en punto libre estilo (no se refiere a puntos, pero a valores ). Cuando se llama a comp1
, hay implícito un tercer parámetro que se pasa al g.f
, que es la composición de las dos funciones g
y f
: (g.f) x
es igual g (f x)
, es decir g
se pasa el resultado de f x
. No existe ningún parámetro x
en comp1
porque está implícita pasa a la función. (Se podría pensar en comp1
como un aplicó parcialmente o curry función de si te hace sentir mejor.)
tipo de comp2
pide dos funciones, una de (a->b)
y otro (b->c)
, así como un parámetro de tipo a
. No hay necesidad de poner a ->
en su firma.
Las dos funciones son realmente equivalentes; uno simplemente utiliza algunos trucos Haskell ser más concisa.
currying . Una función multi-argumento a ML y Haskell, es simplemente azúcar sintáctica para una función de un argumento que devuelve una función; la función que devuelve toma el resto de argumentos.