Recibí la siguiente pregunta en una prueba:
Escribe una función
f
con el siguiente tipoa -> b -> (a -> b)
.a
yb
no debe estar vinculado en ningún sentido, cuanto más corto sea el código, mejor.
Se me ocurrió f a b = \x -> snd ([a,x],b)
. ¿Puedes encontrar algo más pequeño?
Actualmente el ganador es: f _=(.f).const
code-golf
functional-programming
haskell
Radu Stoenescu
fuente
fuente
f = const const
.f _ b _ = b
, pero, dada la solución en la pregunta, sospecho que no se permite un tipo más general .f = id
?f = f
es una solución, ¡así que supongo que las condiciones en el tipo son muy importantes!Respuestas:
Su ejemplo puede reducirse al deshacerse de la función anónima en el lado derecho:
Esto funciona porque el tipo
a -> b -> a -> b
es equivalente aa -> b -> (a -> b)
en Haskell.fuente
f a b x = snd (f x,b)
La función
f _=(.f).const
es en realidad de un tipo más general quef :: a -> b -> (a -> b)
, a saberf :: a -> b -> (c -> b)
. Si no se proporciona una firma de tipo, el sistema de inferencia de tipo infiere un tipo def :: a -> b -> (a -> b)
, pero si incluye la firma de tipof :: a -> b -> (c -> b)
con la misma definición exacta, Haskell la compilará sin problemas e informará tipos consistentes para las aplicaciones parciales de f. Probablemente haya alguna razón profunda por la cual el sistema de inferencia de tipo es más estricto que el sistema de verificación de tipo en este caso, pero no entiendo suficiente teoría de categoría para llegar a una razón de por qué este debería ser el caso. Si no está convencido, puede probarlo usted mismo.fuente
f a b = f a a
. se infiere que es de tipoa -> a -> b
aunque cumple con el tipoa -> b -> c
. es porque sif
no se le da un tipo, solo puede usarse monomórficamente.Dado
ScopedTypeVariables
, se me ocurrió esto:Si reduce tanto mi función como la suya, la mía es un cabello más corto:
Por supuesto, probablemente no se le permita confiar en
ScopedTypeVariables
: P.fuente
f _=(.f).const
( debido a Sassa NF ). Lo que tampoco necesitaScopedTypeVariables
.