Pergunta
Eu tenho uma pergunta a respeito de dois tipos int -> (int -> int) e (int -> int) -> int.Qual é a diferença entre essas duas?
Eu li aqui em algum lugar que o primeiro poderia ser interpretado como uma função que leva um int e retorna uma função que leva e int e retorna um int, que é o mesmo que int ->int -> int.Isso é correto?
Solução
A diferença entre int -> (int -> int)
e int -> int -> int
é insignificante (você realmente só se importaria se tivesse que interoperar com outro idioma).Essas são funções curry que efetivamente pegam dois inteiros e retornam um inteiro (por exemplo, o operador de adição embutido tem um tipo ao longo dessas linhas).
No entanto, ambos são muito diferentes de (int -> int) -> int
, que recebe uma função de inteiros para inteiros e retorna um inteiro.Como outros mencionaram, o único exemplo simples de tal função aplicaria a função dada a um valor específico (por exemplo, fun (f:int->int) -> f 13
).
Outras dicas
Boa pergunta, eu suspeito que, funcionalmente, não há muita diferença.Eu passei um tempo de brincar de tentar descobrir como até mesmo tirar aquelas duas assinaturas.(John Palmer let fun1 i = fun j -> i + j
apenas dá int -> int -> int
por mim)
let add a b = a + b // int -> int -> int
let inc a = add a // int -> (int -> int)
Eu não conseguia pensar em um não-exemplo imaginário para o segundo assinatura:
let foo fn : int -> fn 1 // (int -> int) -> int
(Isso não diretamente resposta a sua pergunta, mas pode dar a alguém algo para mastigar)
Eu realmente não sei F #, mas parece bastante intuitivo (muitas outras linguagens têm as mesmas noções).
- É uma função que recebe um int e retorna uma função que recebe um int e retorna um int
- É uma função que recebe uma função que recebe um int e retorna um int e retorna um int
O primeiro seria uma espécie de função com curry.
Então, vamos ver como seriam as implementações:
primeiro
let func1 i = fun j -> i+j
tem uma assinatura de int -> (int -> int)
observe que func1 2 3
não deve funcionar
EDITAR: Acontece que, devido à forma como a associatividade funciona, isso está bem
mas isso é diferente de
let func2 i j= i+j
que tem um tipo de int -> int -> int
aqui, func2 1 2
está bom
o outro exemplo que podemos criar assim:
let func4 a = a 1
isso terá uma assinatura de ('t->int) -> u
, escolhendo um a
concreto.Observe que func4 1 2
definitivamente não compilará