La función más corta a -> b -> (a -> b) en Haskell


19

Recibí la siguiente pregunta en una prueba:

Escribe una función fcon el siguiente tipo a -> b -> (a -> b). ay bno 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


Si se permite que un tipo más general: f = const const.
hammar

@hammar: o f _ b _ = b, pero, dada la solución en la pregunta, sospecho que no se permite un tipo más general .
Tikhon Jelvis

66
Si se permite un tipo más general, ¿por qué no f = id?
Tom Ellis

77
De hecho, si se permite un tipo más general, entonces f = fes una solución, ¡así que supongo que las condiciones en el tipo son muy importantes!
Tom Ellis

2
No se permite un tipo más general, sus suposiciones eran correctas.
Radu Stoenescu

Respuestas:


11

Su ejemplo puede reducirse al deshacerse de la función anónima en el lado derecho:

f a b x = snd ([a,x],b)

Esto funciona porque el tipo a -> b -> a -> bes equivalente a a -> b -> (a -> b)en Haskell.


44
Modificación ligeramente más corta:f a b x = snd (f x,b)
Ed'ka

5

La función f _=(.f).constes en realidad de un tipo más general que f :: a -> b -> (a -> b), a saber f :: a -> b -> (c -> b). Si no se proporciona una firma de tipo, el sistema de inferencia de tipo infiere un tipo de f :: a -> b -> (a -> b), pero si incluye la firma de tipo f :: 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.


podría ser como el caso de f a b = f a a. se infiere que es de tipo a -> a -> baunque cumple con el tipo a -> b -> c. es porque si fno se le da un tipo, solo puede usarse monomórficamente.
orgulloso Haskeller

Sin embargo
orgulloso Haskeller

4

Dado ScopedTypeVariables, se me ocurrió esto:

f (_::a) b (_::a) = b

Si reduce tanto mi función como la suya, la mía es un cabello más corto:

f(_::a)b(_::a)=b
f a b x=snd([a,x],b)

Por supuesto, probablemente no se le permita confiar en ScopedTypeVariables: P.


3
Esto no es tan corto como f _=(.f).const( debido a Sassa NF ). Lo que tampoco necesita ScopedTypeVariables.
dejó de girar en sentido contrario a las agujas del reloj

Hmm, inicialmente pensé que esto requeriría que el primer y el tercer argumento fueran listas ...
Chris Taylor

@ ChrisTaylor: ¿Demasiado OCaml en la mente? :)
Tikhon Jelvis

Ja, debe ser! ;)
Chris Taylor
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.