Explorar funções
É comum estar em uma situação em que o código parece repetitivo. Ele faz a mesma coisa em vários lugares ou apresenta apenas pequenas diferenças. Em situações como essas, pense em como fazer com que o código fique reutilizável. A maneira de lidar com essa situação é extrair essas expressões e criar uma ou mais funções. Uma função é um bloco de construção fundamental em várias linguagens de programação, assim como no F#.
Uma função
Uma função é uma referência nomeada com um corpo que consiste em uma ou mais expressões. Ela também pode ter parâmetros. Uma função começa com a palavra-chave let
e o nome da função. Depois, há um operador de atribuição e, à direita desse operador, está o corpo da função.
Veja a sintaxe de uma função:
let <function name> <parameters> = <function body>
Um exemplo de função real, como mostrado com a sintaxe de exemplo anterior, é assim:
let add a b = a + b
Neste exemplo, o nome da função é add
e os parâmetros são a
e b
. O corpo da função adiciona os dois parâmetros, a+b
, e retorna o resultado.
Valores retornados
Como você viu no primeiro exemplo, não há nenhuma palavra-chave return
para indicar o que está sendo retornado. No F#, as informações na última linha de uma função é o que está sendo retornado. Considere esta função multilinha:
let addAndMultiply a b c =
let sum = a + b
let product = sum * c
product
Ao colocar product
na última linha, você é informado sobre o que está sendo retornado. Então, como chamar uma função como essa?
Chamar uma função
Para chamar (ou invocar) uma função, use o nome da função e adicione os parâmetros que deseja passar para ela separados por um caractere de espaço. Por exemplo, para chamar a função addAndMultiply()
, insira o seguinte código:
addAndMultiply 2 3 3 // 15
Para ver os resultados da função, você pode atribuí-la a uma variável ou imprimi-la diretamente, desta forma:
let sum = addAndMultiply 2 3 3
printfn "%i" sum
// OR
printfn "%i" (addAndMultiply 2 3 3)
Tipos inferidos
Vamos usar o código a seguir:
let add a b = a + b
let sum = add 2 2
let concat = add "hello" "world" // will give compilation error
Esse código falha na última linha com a seguinte mensagem:
error FS0001: This expression was expected to have type
'int'
but here has type
'string'
O motivo da falha é que o F# já determinou qual tipo de parâmetro deve ser usado, nesse caso, ele optou por inteiro. O motivo pelo qual ele optou por inteiro foi devido às informações na segunda linha, let sum = add 2 2
. A função add()
foi usada de uma forma que declarou que o tipo de parâmetro era definitivamente inteiro.
Se a segunda linha não existisse, o código funcionaria:
let add a b = a + b
// let sum = add 2 2
let concat = add "hello" "world" // will work
O compilador vê que o primeiro uso da função é feito com cadeias de caracteres e conclui que o tipo do parâmetro é cadeia de caracteres. Portanto, o contexto e o primeiro uso inferem o tipo.
Tipos explícitos
Há situações em que você deseja ser explícito quanto aos tipos de parâmetros a serem adotados e o que a função retornará. A especificação ajuda a legibilidade, mesmo que, provavelmente, isso não seja necessário para o compilador.
Veja a seguinte função como exemplo:
let convert a =
int a
Para adicionar tipos a ela, adicione :<type>
, desta forma:
let convert (a:string) =
int a
O parâmetro agora tem o tipo string
por meio do código let convert (a:string)
. Agora você pode ser ainda mais explícito, adicionando um tipo de retorno. Para fazer isso, adicione outro :<type>
logo após o parâmetro:
let convert (a:string) :int =
int a
Agora o parâmetro está entre parênteses, como mostrado em (a:string)
. O tipo de retorno é a última anotação :<type>
a ser executada, que é :int
. O F# é inteligente o bastante para entender a maioria dos cenários, mas às vezes você precisa ajudar o código sendo mais explícito. Outro benefício da adição de tipos é que fica mais fácil para que outros desenvolvedores entendam o que está acontecendo.