O que significa -> significa em F #?
-
01-07-2019 - |
Pergunta
Eu tenho tentado entrar em F # e fora por um tempo, mas eu continuo recebendo adiadas. Por quê?
Porque não importa qual recurso 'novatos' Eu tento olhar para eu ver exemplos muito simples que começar a usar o ->
operador.
No entanto, em nenhum lugar achei ainda que fornece uma simples explicação clara dos meios que este operador. É como se ele deve ser tão óbvio que ele não precisa de explicação até mesmo para iniciantes completos.
I deve, portanto, ser muito densa ou talvez seja quase 3 décadas de experiência anterior me segurando.
Pode alguém por favor, explicar ou apontar para um recurso verdadeiramente acessível que explica isso?
Solução
'->' não é um operador. Ele aparece no # sintaxe F em um número de lugares, e seu significado depende de como ele é usado como parte de uma construção maior.
Dentro de um tipo, '->' descreve os tipos de funções como as pessoas têm descrito acima. Por exemplo
let f : int -> int = ...
diz que 'f' é uma função que leva um int e retorna um int.
Dentro de um lambda ( "coisa que começa com 'diversão' palavra-chave"), '->' é a sintaxe que separa os argumentos do corpo. Por exemplo
fun x y -> x + y + 1
é uma expressão que define uma função dois argumentos com a implementação dada.
Dentro de uma construção "match", '->' é a sintaxe que separa os padrões do código que deve ser executado se o padrão é correspondido. Por exemplo, em
match someList with
| [] -> 0
| h::t -> 1
o material para a esquerda de cada '->'. São padrões, e as coisas à direita é o que acontece se o padrão da esquerda foi combinado
A dificuldade de entendimento pode ser enraizada na suposição equivocada de que '->' é "um operador" com um único significado. Uma analogia pode ser "" em C #, se você nunca viu qualquer código antes, e tentar analisar o "" operador a partir do olhar "obj.Method" e "3,14" e "System.Collections", você pode ficar muito confuso, porque o símbolo tem significados diferentes em contextos diferentes. Depois de saber o suficiente da língua para reconhecer esses contextos, no entanto, as coisas tornam-se claras.
Outras dicas
Basicamente, significa "mapeia para". Leia-lo dessa forma ou como "se transforma em" ou algo parecido.
Assim, a partir do F # em 20 minutos tutorial,
> List.map (fun x -> x % 2 = 0) [1 .. 10];;
val it : bool list
= [false; true; false; true; false; true; false; true; false; true]
O código (diversão i -> i% 2 = 0) define uma função anônima, chamado de lambda expressão, que tem um parâmetro x e a função retorna o resultado de "x % 2 = 0" , que é ou não é x mesmo.
A primeira pergunta - você está familiarizado com expressões lambda em C #? Se assim o -> em F # é o mesmo que o => em C # (eu acho que você lê-lo 'vai para')
.O operador -> também podem ser encontradas no contexto de correspondência de padrões
match x with
| 1 -> dosomething
| _ -> dosomethingelse
Eu não tenho certeza se esta é também uma expressão lambda, ou outra coisa, mas acho que o 'vai para' ainda se mantém.
Talvez o que você está realmente se referindo é 'respostas enigmáticas' o # do analisador F:
> let add a b = a + b
val add: int -> int -> int
Isto significa (como a maioria dos exemplos explicar) que add é um 'val' que leva dois inteiros e retorna um int. Para mim, este foi totalmente opaco para começar. Quer dizer, como eu sei que add não é um val que leva um int e retorna dois ints?
Bem, a coisa é que, em certo sentido, ele faz. Se eu lhe adicionar apenas um int, eu voltar um (int -> int):
> let inc = add 1
val inc: int -> int
Este (currying) é uma das coisas que faz F # tão sexy, para mim.
Para informações úteis sobre F #, eu descobri que os blogs são muito mais útil que qualquer um dos 'documentos' oficial: Aqui estão alguns nomes para check-out
- Dustin Campbell (que de diditwith.net, citado em outra resposta)
- Don Symes ( 'o' homem)
- Tomasp.net (aka Tomas Petricek )
- Andrew Kennedy (para unidades de medida)
- Fsharp.it (famoso para as soluções de projeto Euler)
- http://lorgonblog.spaces.live.com/Blog (aka Brian )
- Jomo Fisher
(a -> b) "a função de um para b" meios. Em tipo de anotação, denota um tipo de função. Por exemplo, f: (int -> String) meios que f refere-se a uma função que leva um número inteiro e retorna uma cadeia de caracteres. É também usado como um contstructor de tais valores, que na
val f : (int -> int) = fun n -> n * 2
o que cria um valor que é uma função de um número n para que mesmo número multiplicado por dois.
Há uma abundância de grandes respostas aqui já, eu só quero acrescentar à conversa uma outra maneira de pensar sobre isso.
'->' significa função.
'a ->' b é uma função que recebe um 'a e retorna um' b
( 'a * 'b) -> (' c * 'd) é uma função que recebe o tuplo de tipo (' a, 'b), e retorna um tuplo de (' c,' d). Tais como int / String Retorna flutuar / char.
Onde fica interessante é no caso cascata de 'a ->' b -> 'c. Esta é uma função que recebe um 'a e retorna uma função (' b -> 'c), ou uma função que recebe um' b -.> C
Então, se você escrever: seja f X Y Z = ()
O tipo será f: 'a ->' b -> 'c -> unidade, por isso, se você só aplicou o primeiro parâmetro, o resultado seria uma função curry' b -> 'c ->' unidade.
A partir Microsoft :
tipos de função são os tipos de dado de primeira classe e os valores da função são int escrita -> int. Eles são iguais aos tipos de delegado .NET, a não ser que Não são dados nomes. Todas as funções F # identificadores pode ser usado como primeira classe os valores da função, e anônimo Os valores de função podem ser criadas usando o (diversão ... -> ...). forma de expressão
Muitos grandes respostas para estas questões, graças pessoas. Eu gostaria de colocar aqui uma resposta editável que traz coisas juntos.
Para aqueles familiarizados com C # entendimento -> sendo o mesmo que => expressão lamba é um bom primeiro passo. Esse uso é: -
fun x y -> x + y + 1
Pode ser entendido como o equivalente a: -
(x, y) => x + y + 1;
No entanto fica claro que -> tem um significado mais fundemental que decorre desde o conceito de que uma função que recebe dois parâmetros, tais como o acima pode ser reduzido (que é o termo correto?) Para uma série de funções tendo apenas um parâmetro.
Assim, quando o anterior é descrito em como isto: -
Int -> Int -> Int
É realmente ajudou a saber que -> é associativa direito daí o acima podem ser considerados: -
Int -> (Int -> Int)
Aha! Nós temos uma função que leva Int e volta (Int -> Int). (? Uma função curry)
A explicação que -> também pode aparecer como parte do tipo definiton também ajudou. (Int -> Int) é do tipo de qualquer de função que leva uma Int e retorna um int
.Também útil é o -> aparece em outra sintaxe, como correspondência, mas não ele não tem o mesmo significado? Isso está correto? Eu não tenho certeza que é. Eu suspeito que ele tem o mesmo significado, mas eu não tenho o vocabulário para expressar isso ainda.
Observe o propósito de esta resposta não é para desovar mais respostas, mas para ser editado colaborativamente por vocês para criar uma resposta mais definitiva. Utlimately seria bom que todas as uncertainies e Fluf (tal como neste parágrafo) ser removido e melhores exemplos adicionado. Vamos tentar manter esta resposta o mais acessível para os não iniciados possível.
No contexto da definição de uma função, que é semelhante ao =>
da expressão lambda em C # 3.0.
F#: let f = fun x -> x*x
C#: Func<int, int> f = x => x * x;
O ->
em F # também é usado na correspondência de padrões, onde ela significa: se a expressão corresponde a parte entre |
e ->
, então o que vem depois ->
deve ser devolvido como o resultado:
let isOne x = match x with
| 1 -> true
| _ -> false
A coisa agradável sobre linguagens como Haskell (que é muito semelhante em F #, mas eu não sei a sintaxe exata - isto deve ajudar a compreender ->, embora) é que você pode aplicar apenas partes do argumento, para criar curry funções:
adder n x y = n + x + y
Em outras palavras: "dá-me três coisas, e eu vou adicioná-los juntos". Quando você joga os números para ele, o compilador irá inferir os tipos de n x e y. Digamos que você escrever
adder 1 2 3
O tipo de 1, 2 e 3 é Int. Portanto:
adder :: Int -> Int -> Int -> Int
Isto é, dá-me três inteiros, e eu me tornarei um inteiro, finalmente, ou a mesma coisa que dizer:
five :: Int
five = 5
Mas, aqui está a parte boa! Tente isto:
add5 = adder 5
Como você se lembra, víbora leva um int, um int, um int, e lhe dá de volta um int. No entanto, isso não é toda a verdade, como você verá em breve. Na verdade, add5 terá este tipo:
add5 :: Int -> Int -> Int
Será como se você tiver "arrancado" dos inteiros (mais à esquerda), e colou-lo diretamente para a função. Olhando mais de perto a assinatura da função, notamos que a -> são associativa à direita, ou seja:
.addder :: Int -> (Int -> (Int -> Int))
Isso deve deixar bem claro: Quando você dá víbora o primeiro inteiro, vai avaliar a tudo o que está à direita da primeira seta, ou:
add5andtwomore :: Int -> (Int -> Int)
add5andtwomore = adder 5
Agora você pode usar add5andtwomore em vez de "víbora 5". Dessa forma, você pode aplicar outro inteiro para chegar (digamos) "add5and7andonemore":
add5and7andonemore :: Int -> Int
add5and7andonemore = adder 5 7
Como você vê, add5and7andonemore quer exatamente outro argumento, e quando você dá a ele um, de repente se tornará um inteiro!
> add5and7andonemore 9
=> ((add5andtwomore) 7) 9
=> ((adder 5) 7) 9)
<=> adder 5 7 9
Substituindo os parâmetros para adder (n x y) para (5 7 9), obtemos:
> adder 5 7 9 = 5 + 7 + 9
=> 5 + 7 + 9
=> 21
Na verdade , mais também é apenas uma função que leva um int e lhe dá de volta outra int, assim que o acima é realmente mais como:
> 5 + 7 + 9
=> (+ 5 (+ 7 9))
=> (+ 5 16)
=> 21
Não que você vá!