Pregunta
Tengo una pregunta sobre dos tipos int -> (int -> int) y (int -> int) -> int.¿Cuál es la diferencia entre estos dos?
Leí aquí en alguna parte que el primero podría interpretarse como una función que toma un int y devuelve una función que toma un int y devuelve un int, que es lo mismo que int ->int -> int.¿Es esto correcto?
Solución
La diferencia entre int -> (int -> int)
y int -> int -> int
es insignificante (realmente solo le importaría si tuviera que interoperar con otro idioma).Estas son funciones curry que efectivamente toman dos números enteros y devuelven un número entero (por ejemplo, el operador de suma incorporado tiene un tipo a lo largo de estas líneas).
Sin embargo, ambos son muy diferentes de (int -> int) -> int
, que toma una función de enteros a enteros y devuelve un entero.Como han mencionado otros, el único ejemplo simple de tal función aplicaría la función dada a un valor específico (por ejemplo, fun (f:int->int) -> f 13
).
Otros consejos
Buena pregunta, sospecho que funcionalmente no hay mucha diferencia.Pasé un tiempo jugueteando tratando de descubrir cómo conseguir esas dos firmas.(John Palmer let fun1 i = fun j -> i + j
solo da int -> int -> int
para mí)
let add a b = a + b // int -> int -> int
let inc a = add a // int -> (int -> int)
No se me ocurrió un ejemplo no artificial para la segunda firma:
let foo fn : int -> fn 1 // (int -> int) -> int
(Esto no responde directamente a su pregunta, pero puede darle a otra persona algo que analizar)
Realmente no sé F #, pero parece bastante intuitivo (muchos otros lenguajes tienen las mismas nociones).
- Es una función que toma un int y devuelve una función que toma un int y devuelve un int
- Es una función que toma una función que toma un int y devuelve un int, y devuelve un int
La primera sería una especie de función al curry.
Entonces, veamos cómo se verían las implementaciones:
primero
let func1 i = fun j -> i+j
esto tiene una firma de int -> (int -> int)
tenga en cuenta que func1 2 3
no debería funcionar
EDITAR: Resulta que debido a la forma en que funciona la asociatividad, esto en realidad está bien.
pero esto es diferente a
let func2 i j= i+j
que tiene un tipo de int -> int -> int
aquí func2 1 2
está bien
El otro ejemplo lo podemos crear así:
let func4 a = a 1
esto tendrá una firma de ('t->int) -> u
recogiendo un concreto a
trabajará.Tenga en cuenta que func4 1 2
definitivamente no compilará